import json
import threading
import time
import base64
import os
from datetime import datetime
from PyQt6.QtWidgets import (QFrame, QVBoxLayout, QHBoxLayout, QLabel, 
                             QPushButton, QComboBox, QWidget, QCheckBox, QSizePolicy,
                             QTextEdit, QListWidget, QListWidgetItem, QSplitter,
                             QDialog, QLineEdit, QFormLayout, QMessageBox,
                             QTableWidget, QTableWidgetItem, QHeaderView, QAbstractItemView,
                             QFileDialog, QProgressBar, QSlider, QInputDialog)
from PyQt6.QtCore import Qt, pyqtSignal, QTimer, QThread, QDateTime, QUrl
from PyQt6.QtGui import QColor, QFont
from PyQt6.QtMultimedia import QMediaRecorder, QAudioInput, QMediaFormat, QMediaCaptureSession, QMediaPlayer, QAudioOutput
from PyQt6.QtMultimediaWidgets import QVideoWidget
from http_client import http_client
from database import db_manager
from utils.style_manager import StyleManager

class MessagePage(QFrame):
    message_finished = pyqtSignal()
    task_completed = pyqtSignal(str)  # 用于通知任务完成
    
    def __init__(self, parent=None):
        super().__init__(parent)
        # 初始化模板数据
        self.templates = []
        self.load_templates()
        
        # 初始化任务状态
        self.common_task_running = False
        self.personal_task_running = False
        
        self.setup_ui()
        # 启动队列监控
        self.start_queue_monitor()
        # 信号连接
        from websocket_client import websocket_client
        websocket_client.consent_finished.connect(self.refresh_data)
        self.message_finished.connect(self.refresh_data)
        self.task_completed.connect(self.on_task_completed)
        
    def closeEvent(self, event):
        """页面关闭时停止队列监控"""
        self.stop_queue_monitor()
        super().closeEvent(event)
        
    def setup_ui(self):
        """设置任务消息页面UI"""
        # 设置页面样式
        StyleManager.set_frame_style(self, "panel")
        
        page_layout = QVBoxLayout(self)
        page_layout.setSpacing(8)
        page_layout.setContentsMargins(8, 8, 8, 8)
        
        # 创建 Tab 按钮区域
        self.create_tab_buttons()
        page_layout.addWidget(self.tab_button_frame)
        
        # 创建内容容器
        self.create_content_container()
        page_layout.addWidget(self.content_container)
        
        # 默认显示 AB 互打页面
        self.current_tab = "ab"
        self.show_tab_content("ab")
        self.update_tab_styles("ab")
    
    def create_common_chat_panel(self):
        """创建共同群聊面板"""
        self.common_chat_panel = QFrame()
        StyleManager.set_frame_style(self.common_chat_panel, "panel")
        
        layout = QVBoxLayout(self.common_chat_panel)
        layout.setSpacing(8)
        layout.setContentsMargins(10, 10, 10, 10)
        
        # 标题
        title_label = QLabel("共同群聊")
        StyleManager.set_label_style(title_label, "title")
        layout.addWidget(title_label)
        
        # 操作按钮行
        button_layout = QHBoxLayout()
        button_layout.setSpacing(5)
        
        buttons = [
            ("全选", "#28a745"),  # 全选共同群聊
            ("反选", "#ffc107"),  # 反选共同群聊
            ("清除今日已回复", "#dc3545")
        ]
        
        for btn_text, color in buttons:
            btn = QPushButton(btn_text)
            btn.setFixedHeight(28)
            
            # 根据按钮文本设置样式类
            if btn_text == "全选":
                StyleManager.set_button_style(btn, "select-all")
                btn.clicked.connect(self.select_all_common_chats)
            elif btn_text == "反选":
                StyleManager.set_button_style(btn, "invert-select")
                btn.clicked.connect(self.invert_common_chat_selection)
            elif btn_text == "清除今日已回复":
                StyleManager.set_button_style(btn, "clear-btn")
                btn.clicked.connect(self.clear_today_replies_common)
            
            button_layout.addWidget(btn)
        
        layout.addLayout(button_layout)
        
        # 群聊列表
        self.common_chat_list = QListWidget()
        StyleManager.set_list_widget_style(self.common_chat_list, "chat-list")
        
        # 设置多选模式
        self.common_chat_list.setSelectionMode(QListWidget.SelectionMode.MultiSelection)
        
        layout.addWidget(self.common_chat_list)
        
        # 群聊操作区域
        self.create_chat_operation_area(layout, "common")
    
    def create_chat_list_panel(self):
        """创建聊天列表面板"""
        self.chat_list_panel = QFrame()
        StyleManager.set_frame_style(self.chat_list_panel, "chat-list-panel")
        
        layout = QVBoxLayout(self.chat_list_panel)
        layout.setSpacing(8)
        layout.setContentsMargins(10, 10, 10, 10)
        
        # 标题
        title_label = QLabel("在线账号列表")
        StyleManager.set_label_style(title_label, "panel-title")
        layout.addWidget(title_label)
        
        # 账号列表显示区域
        self.account_list = QListWidget()
        StyleManager.set_list_widget_style(self.account_list, "account-list")
        
        # 设置账号列表选择模式 - 只能选择一个账号
        self.account_list.setSelectionMode(QListWidget.SelectionMode.SingleSelection)
        
        # 连接选择变化信号
        self.account_list.itemSelectionChanged.connect(self.on_account_selection_changed)
        
        # 添加A/B账号选择按钮
        account_buttons_layout = QHBoxLayout()
        
        self.select_a_btn = QPushButton("设为A账号")
        StyleManager.set_button_style(self.select_a_btn, "small")
        self.select_a_btn.clicked.connect(self.set_as_account_a)
        self.select_a_btn.setEnabled(False)
        account_buttons_layout.addWidget(self.select_a_btn)
        
        self.select_b_btn = QPushButton("设为B账号")
        StyleManager.set_button_style(self.select_b_btn, "small")
        self.select_b_btn.clicked.connect(self.set_as_account_b)
        self.select_b_btn.setEnabled(False)
        account_buttons_layout.addWidget(self.select_b_btn)
        
        self.clear_ab_btn = QPushButton("清除A/B")
        StyleManager.set_button_style(self.clear_ab_btn, "small")
        self.clear_ab_btn.clicked.connect(self.clear_ab_accounts)
        self.clear_ab_btn.setEnabled(False)
        account_buttons_layout.addWidget(self.clear_ab_btn)
        
        account_buttons_layout.addStretch()
        layout.addLayout(account_buttons_layout)
        
        # 添加A/B账号显示标签
        ab_info_layout = QHBoxLayout()
        
        self.account_a_label = QLabel("A账号: 未选择")
        StyleManager.set_label_style(self.account_a_label, "status-info")
        ab_info_layout.addWidget(self.account_a_label)
        
        self.account_b_label = QLabel("B账号: 未选择")
        StyleManager.set_label_style(self.account_b_label, "status-info")
        ab_info_layout.addWidget(self.account_b_label)
        
        layout.addLayout(ab_info_layout)
        
        layout.addWidget(self.account_list)
        
        # 初始化A/B账号
        self.account_a = None
        self.account_b = None
        
        # 刷新账号列表
        self.refresh_account_list()
    
    def refresh_account_list(self):
        """刷新在线账号列表 - 智能刷新，保持选中状态"""
        try:
            # 获取当前选中的项目
            selected_items = self.account_list.selectedItems()
            selected_user_names = []
            for item in selected_items:
                account_data = item.data(Qt.ItemDataRole.UserRole)
                if account_data:
                    selected_user_names.append(account_data.get('user_name', ''))
            
            # 获取在线账号
            online_accounts = db_manager.get_online_accounts()
            
            if not online_accounts:
                # 如果没有在线账号，显示提示信息
                self.account_list.clear()
                item = QListWidgetItem("暂无在线账号")
                item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)  # 不可选择
                self.account_list.addItem(item)
                return
            
            # 获取当前列表中的账号信息
            current_accounts = {}
            for i in range(self.account_list.count()):
                item = self.account_list.item(i)
                if item and item.data(Qt.ItemDataRole.UserRole):
                    account_data = item.data(Qt.ItemDataRole.UserRole)
                    user_name = account_data.get('user_name', '')
                    if user_name:
                        current_accounts[user_name] = {
                            'item': item,
                            'data': account_data
                        }
            
            # 检查是否需要完全刷新
            new_accounts = {acc.get('user_name', ''): acc for acc in online_accounts}
            current_user_names = set(current_accounts.keys())
            new_user_names = set(new_accounts.keys())
            
            # 如果账号列表有变化，进行完全刷新
            if current_user_names != new_user_names:
                self._perform_full_refresh(online_accounts, selected_user_names)
                return
            
            # 检查现有账号的状态是否有变化
            has_changes = False
            for user_name, account in new_accounts.items():
                if user_name in current_accounts:
                    current_data = current_accounts[user_name]['data']
                    # 检查关键状态字段是否有变化
                    if (current_data.get('status') != account.get('status') or
                        current_data.get('login_time') != account.get('login_time') or
                        current_data.get('nick_name') != account.get('nick_name')):
                        has_changes = True
                        break
            
            # 如果没有变化，直接恢复选中状态并返回
            if not has_changes:
                self._restore_selection(selected_user_names)
                return
            
            # 有变化时，更新变化的项目
            self._update_changed_items(current_accounts, new_accounts, selected_user_names)
            
        except Exception as e:
            print(f"刷新账号列表失败: {e}")
            # 显示错误信息
            self.account_list.clear()
            item = QListWidgetItem("加载账号列表失败")
            item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
            self.account_list.addItem(item)
    
    def _perform_full_refresh(self, online_accounts, selected_user_names):
        """执行完全刷新"""
        self.account_list.clear()
        
        for account in online_accounts:
                # 优先显示昵称，如果没有昵称则显示用户名
                display_name = account.get('nick_name') or account.get('user_name', '未知账号')
                
                # 创建列表项
                item = QListWidgetItem(display_name)
                
                # 设置工具提示显示详细信息
                tooltip = f"用户名: {account.get('user_name', '')}\n"
                if account.get('nick_name'):
                    tooltip += f"昵称: {account.get('nick_name', '')}\n"
                if account.get('alias'):
                    tooltip += f"别名: {account.get('alias', '')}\n"
                if account.get('bind_mobile'):
                    tooltip += f"手机: {account.get('bind_mobile', '')}\n"
                tooltip += f"登录时间: {account.get('login_time', '')}"
                
                item.setToolTip(tooltip)
                
                # 存储账号信息到item的data中
                item.setData(Qt.ItemDataRole.UserRole, account)
                
                self.account_list.addItem(item)
            
        # 恢复选中状态
        self._restore_selection(selected_user_names)
    
    def _update_changed_items(self, current_accounts, new_accounts, selected_user_names):
        """更新发生变化的项目"""
        for user_name, new_account in new_accounts.items():
            if user_name in current_accounts:
                current_item = current_accounts[user_name]['item']
                current_data = current_accounts[user_name]['data']
                
                # 检查是否需要更新
                if (current_data.get('status') != new_account.get('status') or
                    current_data.get('login_time') != new_account.get('login_time') or
                    current_data.get('nick_name') != new_account.get('nick_name')):
                    
                    # 更新显示名称
                    display_name = new_account.get('nick_name') or new_account.get('user_name', '未知账号')
                    current_item.setText(display_name)
                    
                    # 更新工具提示
                    tooltip = f"用户名: {new_account.get('user_name', '')}\n"
                    if new_account.get('nick_name'):
                        tooltip += f"昵称: {new_account.get('nick_name', '')}\n"
                    if new_account.get('alias'):
                        tooltip += f"别名: {new_account.get('alias', '')}\n"
                    if new_account.get('bind_mobile'):
                        tooltip += f"手机: {new_account.get('bind_mobile', '')}\n"
                    tooltip += f"登录时间: {new_account.get('login_time', '')}"
                    current_item.setToolTip(tooltip)
                    
                    # 更新存储的数据
                    current_item.setData(Qt.ItemDataRole.UserRole, new_account)
        
        # 恢复选中状态
        self._restore_selection(selected_user_names)
    
    def _restore_selection(self, selected_user_names):
        """恢复选中状态"""
        for i in range(self.account_list.count()):
            item = self.account_list.item(i)
            if item and item.data(Qt.ItemDataRole.UserRole):
                account_data = item.data(Qt.ItemDataRole.UserRole)
                user_name = account_data.get('user_name', '')
                if user_name in selected_user_names:
                    item.setSelected(True)
    
    def get_selected_accounts(self):
        """获取选中的账号列表
        
        Returns:
            List[Dict]: 选中的账号信息列表
        """
        selected_accounts = []
        for i in range(self.account_list.count()):
            item = self.account_list.item(i)
            if item.isSelected():
                account_data = item.data(Qt.ItemDataRole.UserRole)
                if account_data:
                    selected_accounts.append(account_data)
        return selected_accounts
    
    def get_all_online_accounts(self):
        """获取所有在线账号（用于全选功能）
        
        Returns:
            List[Dict]: 所有在线账号信息列表
        """
        all_accounts = []
        for i in range(self.account_list.count()):
            item = self.account_list.item(i)
            account_data = item.data(Qt.ItemDataRole.UserRole)
            if account_data:
                all_accounts.append(account_data)
        return all_accounts
    
    def on_account_selection_changed(self):
        """账号选择变化时的处理"""
        selected_items = self.account_list.selectedItems()
        
        # 启用/禁用按钮
        self.select_a_btn.setEnabled(len(selected_items) == 1)
        self.select_b_btn.setEnabled(len(selected_items) == 1)
        self.clear_ab_btn.setEnabled(self.account_a is not None or self.account_b is not None)
    
    def set_as_account_a(self):
        """将选中的账号设为A账号"""
        selected_items = self.account_list.selectedItems()
        if len(selected_items) == 1:
            account_data = selected_items[0].data(Qt.ItemDataRole.UserRole)
            if account_data:
                self.account_a = account_data
                display_name = account_data.get('nick_name') or account_data.get('user_name', '未知账号')
                self.account_a_label.setText(f"A账号: {display_name}")
                StyleManager.set_label_style(self.account_a_label, "status-success")
                print(f"已设置A账号: {display_name}")
                
                # 如果B账号也已设置，刷新共同群聊列表
                if self.account_b is not None:
                    self.refresh_common_chat_list()
    
    def set_as_account_b(self):
        """将选中的账号设为B账号"""
        selected_items = self.account_list.selectedItems()
        if len(selected_items) == 1:
            account_data = selected_items[0].data(Qt.ItemDataRole.UserRole)
            if account_data:
                self.account_b = account_data
                display_name = account_data.get('nick_name') or account_data.get('user_name', '未知账号')
                self.account_b_label.setText(f"B账号: {display_name}")
                StyleManager.set_label_style(self.account_b_label, "status-success")
                print(f"已设置B账号: {display_name}")
                
                # 如果A账号也已设置，刷新共同群聊列表
                if self.account_a is not None:
                    self.refresh_common_chat_list()
    
    def clear_ab_accounts(self):
        """清除A/B账号设置"""
        self.account_a = None
        self.account_b = None
        self.account_a_label.setText("A账号: 未选择")
        self.account_b_label.setText("B账号: 未选择")
        StyleManager.set_label_style(self.account_a_label, "status-info")
        StyleManager.set_label_style(self.account_b_label, "status-info")
        print("已清除A/B账号设置")
        
        # 清空共同群聊列表
        self.refresh_common_chat_list()
    
    def get_account_a(self):
        """获取A账号
        
        Returns:
            Dict: A账号信息，如果未设置则返回None
        """
        return self.account_a
    
    def get_account_b(self):
        """获取B账号
        
        Returns:
            Dict: B账号信息，如果未设置则返回None
        """
        return self.account_b
    
    def get_ab_accounts(self):
        """获取A/B账号对
        
        Returns:
            Tuple[Dict, Dict]: (A账号信息, B账号信息)，如果未设置则对应位置为None
        """
        return self.account_a, self.account_b
    
    def is_ab_accounts_ready(self):
        """检查A/B账号是否已设置
        
        Returns:
            bool: 如果A和B账号都已设置则返回True
        """
        return self.account_a is not None and self.account_b is not None
    
    def get_common_groups(self):
        """获取A/B账号的共同群聊
        
        Returns:
            List[Dict]: 共同群聊列表
        """
        if not self.is_ab_accounts_ready():
            return []
        
        try:
            from database import db_manager
            
            # 获取A账号的群聊
            account_a_groups = db_manager.get_user_groups(self.account_a.get('user_name'))
            # 获取B账号的群聊
            account_b_groups = db_manager.get_user_groups(self.account_b.get('user_name'))
            
            # 创建A账号群聊的qid集合
            account_a_qids = {group['qid'] for group in account_a_groups if group['status'] == 'active'}
            # 创建B账号群聊的qid集合
            account_b_qids = {group['qid'] for group in account_b_groups if group['status'] == 'active'}
            
            # 找到共同的qid
            common_qids = account_a_qids.intersection(account_b_qids)
            
            # 获取共同群聊的详细信息
            common_groups = []
            for group in account_a_groups:
                if group['qid'] in common_qids and group['status'] == 'active':
                    common_groups.append(group)
            
            print(f"找到 {len(common_groups)} 个共同群聊")
            return common_groups
            
        except Exception as e:
            print(f"获取共同群聊失败: {e}")
            return []
    
    def refresh_common_chat_list(self):
        """刷新共同群聊列表"""
        try:
            # 清空现有列表
            self.common_chat_list.clear()
            
            if not self.is_ab_accounts_ready():
                # 如果没有设置A/B账号，显示提示信息
                item = QListWidgetItem("请先设置A和B账号")
                item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
                self.common_chat_list.addItem(item)
                return
            
            # 获取共同群聊
            common_groups = self.get_common_groups()
            
            if not common_groups:
                # 如果没有共同群聊，显示提示信息
                item = QListWidgetItem("A/B账号没有共同的群聊")
                item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
                self.common_chat_list.addItem(item)
                return
            
            # 添加共同群聊到列表
            for group in common_groups:
                # 创建显示文本
                display_text = f"{group['group_name']} (qid: {group['qid']})"
                
                # 创建列表项
                item = QListWidgetItem(display_text)
                
                # 设置工具提示显示详细信息
                tooltip = f"群名称: {group['group_name']}\n"
                tooltip += f"群ID: {group['qid']}\n"
                tooltip += f"邀请人: {group['inviter_name'] or '未知'}\n"
                tooltip += f"加入时间: {group['join_time']}\n"
                tooltip += f"状态: {group['status']}"
                
                item.setToolTip(tooltip)
                
                # 存储群聊信息到item的data中
                item.setData(Qt.ItemDataRole.UserRole, group)
                
                self.common_chat_list.addItem(item)
            
            print(f"已加载 {len(common_groups)} 个共同群聊")
            
            # 显示选中状态
            self.show_common_chat_selection_status()
            
        except Exception as e:
            print(f"刷新共同群聊列表失败: {e}")
            # 显示错误信息
            item = QListWidgetItem("加载共同群聊列表失败")
            item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
            self.common_chat_list.addItem(item)
    
    def get_selected_common_groups(self):
        """获取选中的共同群聊列表
        
        Returns:
            List[Dict]: 选中的共同群聊信息列表
        """
        selected_groups = []
        for i in range(self.common_chat_list.count()):
            item = self.common_chat_list.item(i)
            if item.isSelected():
                group_data = item.data(Qt.ItemDataRole.UserRole)
                if group_data:
                    selected_groups.append(group_data)
        return selected_groups
    
    def show_common_chat_selection_status(self):
        """显示共同群聊选中状态"""
        selected_groups = self.get_selected_common_groups()
        total_count = self.common_chat_list.count()
        selected_count = len(selected_groups)
        
        print(f"共同群聊选中状态: {selected_count}/{total_count} 个群聊")
        
        if selected_groups:
            group_names = [g['group_name'] for g in selected_groups]
            print(f"当前选中的群聊: {', '.join(group_names)}")
        else:
            print("当前没有选中任何群聊")
    
    def create_tab_buttons(self):
        """创建 Tab 按钮区域"""
        self.tab_button_frame = QFrame()
        tab_layout = QHBoxLayout(self.tab_button_frame)
        tab_layout.setSpacing(10)
        
        # AB互打 tab 按钮
        self.ab_tab_btn = QPushButton("AB互打")
        self.ab_tab_btn.clicked.connect(self.show_ab_tab)
        self.ab_tab_btn.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: #007bff;
                border: none;
                font-weight: bold;
                font-size: 14px;
                padding: 8px 16px;
            }
            QPushButton:hover {
                color: #0056b3;
                text-decoration: underline;
            }
        """)
        tab_layout.addWidget(self.ab_tab_btn)
        
        # 话术模板 tab 按钮
        self.template_tab_btn = QPushButton("话术模板")
        self.template_tab_btn.clicked.connect(self.show_template_tab)
        self.template_tab_btn.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: #007bff;
                border: none;
                font-weight: bold;
                font-size: 14px;
                padding: 8px 16px;
            }
            QPushButton:hover {
                color: #0056b3;
                text-decoration: underline;
            }
        """)
        tab_layout.addWidget(self.template_tab_btn)
        
        tab_layout.addStretch()
    
    def create_content_container(self):
        """创建内容容器"""
        self.content_container = QWidget()
        content_layout = QVBoxLayout(self.content_container)
        content_layout.setContentsMargins(0, 0, 0, 0)  # 移除边距
        content_layout.setSpacing(0)  # 移除间距
        
        # 设置内容容器的尺寸策略，让它能够拉伸
        self.content_container.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        
        # 创建 AB 互打页面（当前的三列布局）
        self.ab_page = QWidget()
        ab_layout = QVBoxLayout(self.ab_page)
        ab_layout.setContentsMargins(0, 0, 0, 0)  # 移除边距
        ab_layout.setSpacing(0)  # 移除间距
        
        # 设置 AB 页面的尺寸策略，让它能够拉伸
        self.ab_page.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        
        # 创建三列布局的水平分割器
        main_splitter = QSplitter(Qt.Orientation.Horizontal)
        StyleManager.set_splitter_style(main_splitter, "main-splitter")
        
        # 左侧：共同群聊
        self.create_common_chat_panel()
        main_splitter.addWidget(self.common_chat_panel)
        
        # 中间：聊天列表
        self.create_chat_list_panel()
        main_splitter.addWidget(self.chat_list_panel)
        
        # 右侧：不同群聊
        self.create_different_chat_panel()
        main_splitter.addWidget(self.personal_chat_panel)
        
        # 设置三列的初始宽度比例
        main_splitter.setSizes([350, 400, 350])
        main_splitter.setCollapsible(0, False)
        main_splitter.setCollapsible(1, False)
        main_splitter.setCollapsible(2, False)
        
        # 让分割器拉伸填充整个可用空间
        main_splitter.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        
        ab_layout.addWidget(main_splitter)
        
        # 创建话术模板页面
        self.template_page = QWidget()
        template_layout = QVBoxLayout(self.template_page)
        template_layout.setContentsMargins(10, 10, 10, 10)  # 保持一些边距
        template_layout.setSpacing(10)  # 保持一些间距
        
        # 设置话术模板页面的尺寸策略，让它能够拉伸
        self.template_page.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        
        # 话术模板页面的内容
        template_title = QLabel("话术模板管理")
        StyleManager.set_label_style(template_title, "template-title")
        template_layout.addWidget(template_title)
        
        # 话术模板控制区域
        template_control_frame = QFrame()
        template_control_layout = QHBoxLayout(template_control_frame)
        template_control_layout.setSpacing(15)
        
        # 添加话术模板按钮
        add_template_btn = QPushButton("添加模板")
        StyleManager.set_button_style(add_template_btn, "template-btn")
        add_template_btn.clicked.connect(self.add_template)
        template_control_layout.addWidget(add_template_btn)
        
        template_control_layout.addStretch()
        template_layout.addWidget(template_control_frame)
        
        # 话术模板表格
        self.template_table = self.create_template_table()
        self.template_table.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        template_layout.addWidget(self.template_table)
        
        # 初始化表格数据
        self.refresh_template_table()
    
    def create_different_chat_panel(self):
        """创建不同群聊面板"""
        self.personal_chat_panel = QFrame()
        StyleManager.set_frame_style(self.personal_chat_panel, "personal-chat-panel")
        
        layout = QVBoxLayout(self.personal_chat_panel)
        layout.setSpacing(8)
        layout.setContentsMargins(10, 10, 10, 10)
        
        # 标题
        title_label = QLabel("不同群聊")
        StyleManager.set_label_style(title_label, "panel-title")
        layout.addWidget(title_label)
        
        # 操作按钮行
        button_layout = QHBoxLayout()
        button_layout.setSpacing(5)
        
        buttons = [
            ("全选", "#28a745"),  # 全选不同群聊
            ("反选", "#ffc107"),  # 反选不同群聊
            ("清除今日已回复", "#dc3545"),
            ("动态购号", "#17a2b8"),
            ("动态销号", "#6f42c1")
        ]
        
        for btn_text, color in buttons:
            btn = QPushButton(btn_text)
            btn.setFixedHeight(28)
            
            # 根据按钮文本设置样式类
            if btn_text == "全选":
                StyleManager.set_button_style(btn, "select-all")
                btn.clicked.connect(self.select_all_personal_chats)
            elif btn_text == "反选":
                StyleManager.set_button_style(btn, "invert-select")
                btn.clicked.connect(self.invert_personal_chat_selection)
            elif btn_text == "清除今日已回复":
                StyleManager.set_button_style(btn, "clear-btn")
                btn.clicked.connect(self.clear_today_replies_personal)
            elif btn_text == "动态购号":
                StyleManager.set_button_style(btn, "info")
                btn.clicked.connect(self.dynamic_buy_account)
            elif btn_text == "动态销号":
                StyleManager.set_button_style(btn, "warning")
                btn.clicked.connect(self.dynamic_sell_account)
            
            button_layout.addWidget(btn)
        
        layout.addLayout(button_layout)
        
        # 不同群聊列表
        self.personal_chat_list = QListWidget()
        StyleManager.set_list_widget_style(self.personal_chat_list, "chat-list")
        
        # 设置多选模式
        self.personal_chat_list.setSelectionMode(QListWidget.SelectionMode.MultiSelection)
        
        layout.addWidget(self.personal_chat_list)
        
        # 群聊操作区域
        self.create_chat_operation_area(layout, "personal")
    
    def create_chat_operation_area(self, parent_layout, chat_type):
        """创建群聊操作区域"""
        operation_frame = QFrame()
        StyleManager.set_frame_style(operation_frame, "panel")
        
        operation_layout = QVBoxLayout(operation_frame)
        operation_layout.setSpacing(8)
        operation_layout.setContentsMargins(10, 10, 10, 10)
        
        # 话术选择
        sender_layout = QHBoxLayout()
        sender_label = QLabel("选择话术:")
        StyleManager.set_label_style(sender_label, "subtitle")
        sender_label.setFixedWidth(60)
        sender_combo = QComboBox()
        # 加载话术模板选项
        self.load_script_options(sender_combo)
        sender_layout.addWidget(sender_label)
        sender_layout.addWidget(sender_combo)
        operation_layout.addLayout(sender_layout)
        
        # 分组选择
        device_layout = QHBoxLayout()
        device_label = QLabel("选择分组:")
        StyleManager.set_label_style(device_label, "subtitle")
        device_label.setFixedWidth(60)
        device_combo = QComboBox()
        device_combo.addItems(["请选择分组"])
        device_layout.addWidget(device_label)
        device_layout.addWidget(device_combo)
        operation_layout.addLayout(device_layout)
        
        # 保存combo box的引用
        if chat_type == "common":
            self.common_sender_combo = sender_combo
            self.common_device_combo = device_combo
        else:
            self.personal_sender_combo = sender_combo
            self.personal_device_combo = device_combo
        
        # 连接sender_combo的选择变化事件
        sender_combo.currentTextChanged.connect(lambda text: self.on_sender_combo_changed(text, device_combo))
        
        # 任务按钮区域
        task_buttons_layout = QHBoxLayout()
        task_buttons_layout.setSpacing(10)
        
        # 开始任务按钮
        start_btn = QPushButton("开始任务")
        start_btn.setFixedHeight(35)
        StyleManager.set_button_style(start_btn, "success")
        
        # 停止任务按钮
        stop_btn = QPushButton("停止任务")
        stop_btn.setFixedHeight(35)
        StyleManager.set_button_style(stop_btn, "danger")
        
        # 初始状态：开始按钮可用，停止按钮禁用
        stop_btn.setEnabled(False)
        
        if chat_type == "common":
            start_btn.clicked.connect(self.start_common_task)
            stop_btn.clicked.connect(self.stop_common_task)
            # 保存按钮引用
            self.common_start_btn = start_btn
            self.common_stop_btn = stop_btn
        else:
            start_btn.clicked.connect(self.start_personal_task)
            stop_btn.clicked.connect(self.stop_personal_task)
            # 保存按钮引用
            self.personal_start_btn = start_btn
            self.personal_stop_btn = stop_btn
        
        task_buttons_layout.addWidget(start_btn)
        task_buttons_layout.addWidget(stop_btn)
        operation_layout.addLayout(task_buttons_layout)
        
        parent_layout.addWidget(operation_frame)
    
    def setup_data(self):
        """设置页面数据"""
        # 刷新账号列表
        if hasattr(self, 'account_list'):
            self.refresh_account_list()
        
        # 刷新话术下拉框
        self.refresh_script_combos()
    
    # 事件处理方法
    def select_all_common_chats(self):
        """全选共同群聊"""
        selected_count = 0
        total_count = self.common_chat_list.count()
        
        for i in range(total_count):
            item = self.common_chat_list.item(i)
            if item.flags() & Qt.ItemFlag.ItemIsSelectable:  # 只选择可选择的项目
                item.setSelected(True)
                selected_count += 1
        
        print(f"已全选共同群聊: {selected_count}/{total_count} 个群聊")
        
        # 显示选中状态
        selected_groups = self.get_selected_common_groups()
        if selected_groups:
            group_names = [g['group_name'] for g in selected_groups]
            print(f"选中的群聊: {', '.join(group_names)}")
    
    def invert_common_chat_selection(self):
        """反选共同群聊"""
        selected_count = 0
        total_count = self.common_chat_list.count()
        
        for i in range(total_count):
            item = self.common_chat_list.item(i)
            if item.flags() & Qt.ItemFlag.ItemIsSelectable:  # 只选择可选择的项目
                item.setSelected(not item.isSelected())
                if item.isSelected():
                    selected_count += 1
        
        print(f"已反选共同群聊: {selected_count}/{total_count} 个群聊")
        
        # 显示选中状态
        selected_groups = self.get_selected_common_groups()
        if selected_groups:
            group_names = [g['group_name'] for g in selected_groups]
            print(f"选中的群聊: {', '.join(group_names)}")
    
    def clear_today_replies_common(self):
        """清除今日已回复记录"""
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(self, "提示", "已清除今日回复记录")
        print("已清除今日回复记录")
    
    def select_all_personal_chats(self):
        """全选不同群聊"""
        selected_count = 0
        total_count = self.personal_chat_list.count()
        
        for i in range(total_count):
            item = self.personal_chat_list.item(i)
            if item.flags() & Qt.ItemFlag.ItemIsSelectable:  # 只选择可选择的项目
                item.setSelected(True)
                selected_count += 1
        
        print(f"已全选不同群聊: {selected_count}/{total_count} 个群聊")
    
    def invert_personal_chat_selection(self):
        """反选不同群聊"""
        selected_count = 0
        total_count = self.personal_chat_list.count()
        
        for i in range(total_count):
            item = self.personal_chat_list.item(i)
            if item.flags() & Qt.ItemFlag.ItemIsSelectable:  # 只选择可选择的项目
                item.setSelected(not item.isSelected())
                if item.isSelected():
                    selected_count += 1
        
        print(f"已反选不同群聊: {selected_count}/{total_count} 个群聊")
    
    def clear_today_replies_personal(self):
        """清除今日已回复记录（不同群聊）"""
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(self, "提示", "已清除今日回复记录")
        print("已清除今日回复记录")
    
    def dynamic_buy_account(self):
        """动态购号"""
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(self, "动态购号", "动态购号功能正在开发中...")
        print("执行动态购号操作")
    
    def dynamic_sell_account(self):
        """动态销号"""
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(self, "动态销号", "动态销号功能正在开发中...")
        print("执行动态销号操作")
    
    def send_to_common_chats(self):
        """向共同群聊发送消息"""
        # 检查A/B账号是否已设置
        if not self.is_ab_accounts_ready():
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请先设置A和B账号！")
            return
        
        # 获取选中的共同群聊
        selected_groups = self.get_selected_common_groups()
        if not selected_groups:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请选择要发送消息的共同群聊！")
            return
        
        script = self.common_sender_combo.currentText()
        group = self.common_device_combo.currentText()
        
        # 获取A/B账号信息 - 使用user_name作为wxid参数
        account_a_name = self.account_a.get('user_name')  # 使用user_name字段
        account_b_name = self.account_b.get('user_name')  # 使用user_name字段
        
        # 获取选中的群聊名称
        group_names = [g['group_name'] for g in selected_groups]
        
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(
            self, 
            "共同群聊消息", 
            f"已向选中的共同群聊发送消息\n"
            f"A账号: {account_a_name}\n"
            f"B账号: {account_b_name}\n"
            f"目标群聊: {', '.join(group_names)}\n"
            f"选择话术: {script}\n"
            f"选择分组: {group}"
        )
        print(f"向共同群聊发送消息: A={account_a_name}, B={account_b_name}, 群聊={group_names}")
    
    def send_to_personal_chats(self):
        """向不同群聊发送消息"""
        # 检查A/B账号是否已设置
        if not self.is_ab_accounts_ready():
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请先设置A和B账号！")
            return
        
        script = self.personal_sender_combo.currentText()
        group = self.personal_device_combo.currentText()
        
        # 获取A/B账号信息 - 使用user_name作为wxid参数
        account_a_name = self.account_a.get('user_name')  # 使用user_name字段
        account_b_name = self.account_b.get('user_name')  # 使用user_name字段
        
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(
            self, 
            "AB互打消息", 
            f"已向A/B账号发送消息\n"
            f"A账号: {account_a_name}\n"
            f"B账号: {account_b_name}\n"
            f"选择话术: {script}\n"
            f"选择分组: {group}"
        )
        print(f"向A/B账号发送消息: A={account_a_name}, B={account_b_name}")
    
    def start_common_task(self):
        """开始共同群聊任务"""
        if self.common_task_running:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "任务已在运行中！")
            return
        
        # 检查A/B账号是否已设置
        if not self.is_ab_accounts_ready():
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请先设置A和B账号！")
            return
        
        # 获取选中的共同群聊
        selected_groups = self.get_selected_common_groups()
        if not selected_groups:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请选择要执行任务的共同群聊！")
            return
        
        # 获取任务参数
        script = self.common_sender_combo.currentText()
        group = self.common_device_combo.currentText()
        
        # 检查是否选择了话术和分组
        if script == "请选择话术":
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请选择要发送的话术！")
            return
        
        if group == "请选择分组":
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请选择要发送的分组！")
            return
        
        # 更新任务状态
        self.common_task_running = True
        
        # 更新按钮状态
        if hasattr(self, 'common_start_btn'):
            self.common_start_btn.setEnabled(False)
        if hasattr(self, 'common_stop_btn'):
            self.common_stop_btn.setEnabled(True)
        
        # 获取A/B账号信息 - 使用user_name作为wxid参数
        account_a_name = self.account_a.get('user_name')  # 使用user_name字段
        account_b_name = self.account_b.get('user_name')  # 使用user_name字段
        
        # 获取选中的群聊名称
        group_names = [g['group_name'] for g in selected_groups]
        
        # 开始群发消息任务
        self.start_batch_message_task(selected_groups, script, group, account_a_name, account_b_name)
        
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(
            self, 
            "开始共同群聊任务", 
            f"已开始共同群聊任务\n"
            f"A账号: {account_a_name}\n"
            f"B账号: {account_b_name}\n"
            f"目标群聊: {', '.join(group_names)}\n"
            f"选择话术: {script}\n"
            f"选择分组: {group}\n"
            f"消息间隔: 3秒"
        )
        print(f"开始共同群聊任务: A={account_a_name}, B={account_b_name}, 群聊={group_names}")
    
    def start_batch_message_task(self, selected_groups, script, group, account_a_name, account_b_name):
        """开始批量发送消息任务"""
        import threading
        import time
        
        # 获取模板数据
        template = None
        for t in self.templates:
            if t['name'] == script:
                template = t
                break
        
        if not template:
            print(f"未找到模板: {script}")
            return
        
        # 获取模板的对话数据
        dialogues = template.get('dialogues', [])
        if not dialogues:
            print(f"模板 {script} 没有对话数据")
            return
        
        # 获取所有要发送的对话，按照模板中的原始顺序
        messages_to_send = []
        
        for dialogue in dialogues:
            # 检查是否为分组对话
            if dialogue.get('use_groups') and dialogue.get('group_data'):
                group_data = dialogue.get('group_data', {})
                if isinstance(group_data, dict) and group in group_data:
                    # 使用分组内容
                    group_content = group_data[group]
                    message_data = {
                        'message_type': dialogue.get('message_type', 'text'),
                        'content': group_content,
                        'speaker': dialogue.get('speaker', 'A'),
                        'source': 'group'  # 标记为分组对话
                    }
                    messages_to_send.append(message_data)
            # 检查是否为普通模板对话
            elif not dialogue.get('use_groups') and dialogue.get('content'):
                # 使用模板内容
                message_data = {
                    'message_type': dialogue.get('message_type', 'text'),
                    'content': dialogue.get('content', ''),
                    'speaker': dialogue.get('speaker', 'A'),
                    'source': 'template'  # 标记为模板对话
                }
                messages_to_send.append(message_data)
        
        if not messages_to_send:
            print(f"未找到模板 {script} 的有效消息内容")
            return
        
        # 显示对话来源信息
        group_count = len([msg for msg in messages_to_send if msg.get('source') == 'group'])
        template_count = len([msg for msg in messages_to_send if msg.get('source') == 'template'])
        
        print(f"模板 {script} 包含 {len(messages_to_send)} 条对话:")
        print(f"  分组对话: {group_count} 条")
        print(f"  模板对话: {template_count} 条")
        
        for i, msg in enumerate(messages_to_send):
            source_type = "分组" if msg.get('source') == 'group' else "模板"
            print(f"  对话{i+1}: {msg['speaker']} -> {msg['message_type']} -> [{source_type}] {msg['content'][:30]}...")
        
        # 创建任务线程
        def send_messages():
            try:
                print(f"开始向 {len(selected_groups)} 个群聊发送 {len(messages_to_send)} 条消息")
                
                # 外层循环：按消息顺序发送
                for j, message_data in enumerate(messages_to_send):
                    if not self.common_task_running:
                        print("任务已停止")
                        break
                    
                    speaker = message_data.get('speaker', 'A')
                    source_type = "分组" if message_data.get('source') == 'group' else "模板"
                    print(f"正在发送第{j+1}/{len(messages_to_send)}条消息: {speaker} -> {message_data['message_type']} -> [{source_type}]")
                    
                    # 根据说话者选择发送账号
                    if speaker == 'A':
                        sender_account = account_a_name
                    elif speaker == 'B':
                        sender_account = account_b_name
                    else:
                        sender_account = account_a_name  # 默认使用A账号
                    
                    # 内层循环：向所有选中的群聊发送当前消息
                    for i, group_info in enumerate(selected_groups):
                        if not self.common_task_running:
                            print("任务已停止")
                            break
                        
                        group_name = group_info['group_name']
                        print(f"  向群聊 {group_name} 发送消息 ({i+1}/{len(selected_groups)})")
                        
                        # 发送消息到群聊
                        success = self.send_message_to_group(group_info, message_data, sender_account, account_b_name)
                        
                        if success:
                            print(f"    群聊 {group_name} 发送成功")
                        else:
                            print(f"    群聊 {group_name} 发送失败")
                        
                        # 群聊间隔：除了最后一个群聊，等待1秒
                        if i < len(selected_groups) - 1 and self.common_task_running:
                            print(f"    等待1秒后发送下一个群聊...")
                            time.sleep(1)
                    
                    # 消息间隔：除了最后一条消息，等待2秒
                    if j < len(messages_to_send) - 1 and self.common_task_running:
                        print(f"等待2秒后发送下一条消息...")
                        time.sleep(2)
                
                print("批量发送消息任务完成")
                # 发送信号通知任务完成
                self.task_completed.emit("批量发送消息任务完成")
                
            except Exception as e:
                print(f"批量发送消息任务失败: {e}")
                # 发送信号通知任务失败
                self.task_completed.emit(f"批量发送消息任务失败: {e}")
            finally:
                # 任务完成后停止任务
                self.stop_common_task()
        
        # 启动任务线程
        task_thread = threading.Thread(target=send_messages)
        task_thread.daemon = True
        task_thread.start()
    
    def send_message_to_group(self, group_info, message_data, account_a_name, account_b_name):
        """向指定群聊发送消息，根据消息类型自动选择接口"""
        try:
            from http_client import http_client
            
            # 从群聊信息中获取正确的参数
            group_name = group_info.get('group_name', '')
            group_qid = group_info.get('qid', '')  # 使用qid作为to_wxid
            account_user_name = account_a_name  # 使用user_name作为wxid
            
            print(f"{account_user_name} 向群聊 {group_name} 发送消息:")
            
            # 解析消息数据
            message_type = message_data.get('message_type', 'text')
            content = message_data.get('content', '')
            
            # 如果消息类型是auto，则自动检测类型
            if message_type == 'auto':
                message_type = self.detect_message_type(content)
                print(f"  自动检测消息类型: {message_type}")
            else:
                print(f"  指定消息类型: {message_type}")
            
            response = None
            
            # 根据消息类型选择合适的接口
            if message_type == 'text':
                # 发送文本消息
                response = http_client.send_text_message(
                    wxid=account_user_name,  # 使用user_name
                    content=content,
                    to_wxid=group_qid  # 使用qid
                )
                print(f'发送文本：{content} 回复：{response}')
                
            elif message_type == 'link':
                # 发送链接消息
                response = http_client.send_link_message(
                    wxid=account_user_name,  # 使用user_name
                    xml=content,  # 链接内容作为XML发送
                    to_wxid=group_qid  # 使用qid
                )
                print(f"  使用链接接口发送: {content[:50000]}...")
                print(f"responce: {response}")
                
            elif message_type == 'voice':
                # 发送语音消息
                # 语音数据应该包含base64编码和时长信息
                voice_data = content
                if isinstance(voice_data, dict):
                    base64_data = voice_data.get('base64', '')
                    voice_time = voice_data.get('duration', 1)
                else:
                    # 如果content是字符串，假设是base64数据
                    base64_data = content
                    voice_time = 1
                
                response = http_client.send_voice_message(
                    wxid=account_user_name,  # 使用user_name
                    base64=base64_data,
                    to_wxid=group_qid,  # 使用qid
                    voice_time=voice_time
                )
                print(f"  使用语音接口发送: 时长{voice_time}秒")
                
            elif message_type == 'image':
                # 发送图片消息
                response = http_client.send_image_message(
                    wxid=account_user_name,  # 使用user_name
                    base64=content,  # 图片的base64编码
                    to_wxid=group_qid  # 使用qid
                )
                print(f"发送图片回复：{response}")
                
            else:
                # 默认使用文本接口
                print(f"  未知消息类型 '{message_type}'，使用文本接口")
                response = http_client.send_text_message(
                    wxid=account_user_name,  # 使用user_name
                    content=str(content),
                    to_wxid=group_qid  # 使用qid
                )
            
            # 检查响应结果
            if response and response.get('Success') and response.get('Code') == 0:
                print(f"消息发送成功: {group_name}")
                return True
            else:
                error_msg = response.get('Message', '未知错误') if response else '无响应'
                print(f"消息发送失败: {group_name}, 错误: {error_msg}")
                return False
            
        except Exception as e:
            print(f"发送消息到群聊 {group_name} 失败: {e}")
            return False
    
    def detect_message_type(self, content):
        """自动检测消息类型"""
        if not content:
            return 'text'
        
        import re

        # 检测是否为base64编码的图片数据
        if isinstance(content, str) and len(content) > 100 and content.startswith('data:image'):
            return 'image'
        
        # 检测是否为base64编码的语音数据
        if isinstance(content, str) and len(content) > 100 and content.startswith('data:audio'):
            return 'voice'
        
        # 检测是否包含链接
        url_pattern = r'https?://[^\s]+'
        if re.search(url_pattern, content):
            return 'link'
        
        # 检测是否为语音数据字典
        if isinstance(content, dict) and 'base64' in content:
            return 'voice'
        
        # 检测是否为图片数据字典
        if isinstance(content, dict) and 'image_data' in content:
            return 'image'
        
        # 默认为文本
        return 'text'
    
    def on_task_completed(self, message):
        """处理任务完成信号"""
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(self, "任务完成", message)
    
    def test_message_sending(self):
        """测试不同类型的消息发送"""
        from PyQt6.QtWidgets import QMessageBox
        
        # 检查A/B账号是否已设置
        if not self.is_ab_accounts_ready():
            QMessageBox.warning(self, "警告", "请先设置A和B账号！")
            return
        
        account_a_name = self.account_a.get('nick_name') or self.account_a.get('user_name')
        
        # 测试不同类型的消息
        test_messages = [
            {
                'name': '文本消息',
                'data': {'message_type': 'text', 'content': '这是一条测试文本消息'}
            },
            {
                'name': '链接消息', 
                'data': {'message_type': 'link', 'content': 'https://example.com 点击查看详情'}
            },
            {
                'name': '语音消息',
                'data': {'message_type': 'voice', 'content': {'base64': 'test_audio_data', 'duration': 3}}
            },
            {
                'name': '图片消息',
                'data': {'message_type': 'image', 'content': 'test_image_base64_data'}
            },
            {
                'name': '自动检测文本',
                'data': {'message_type': 'auto', 'content': '这是自动检测的文本消息'}
            },
            {
                'name': '自动检测链接',
                'data': {'message_type': 'auto', 'content': '请访问 https://www.example.com 获取更多信息'}
            }
        ]
        
        # 获取第一个群聊进行测试
        selected_groups = self.get_selected_common_groups()
        if not selected_groups:
            QMessageBox.warning(self, "警告", "请选择要测试的群聊！")
            return
        
        test_group_info = selected_groups[0]
        test_group_name = test_group_info['group_name']
        
        # 显示测试信息
        QMessageBox.information(
            self,
            "消息发送测试",
            f"将向群聊 {test_group_name} 发送测试消息\n"
            f"发送账号: {account_a_name}\n"
            f"测试消息类型: 文本、链接、语音、图片"
        )
        
        # 在后台线程中执行测试
        import threading
        import time
        
        def run_test():
            try:
                for i, test_msg in enumerate(test_messages):
                    print(f"测试 {test_msg['name']}...")
                    success = self.send_message_to_group(
                        test_group_info, 
                        test_msg['data'], 
                        account_a_name, 
                        account_a_name
                    )
                    print(f"{test_msg['name']} 测试结果: {'成功' if success else '失败'}")
                    
                    # 等待2秒后发送下一条
                    if i < len(test_messages) - 1:
                        time.sleep(2)
                
                print("所有消息类型测试完成")
                self.task_completed.emit("消息发送测试完成")
                
            except Exception as e:
                print(f"消息发送测试失败: {e}")
                self.task_completed.emit(f"消息发送测试失败: {e}")
        
        test_thread = threading.Thread(target=run_test)
        test_thread.daemon = True
        test_thread.start()
    
    def stop_common_task(self):
        """停止共同群聊任务"""
        if not self.common_task_running:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "没有正在运行的任务！")
            return
        
        # 更新任务状态
        self.common_task_running = False
        
        # 更新按钮状态
        if hasattr(self, 'common_start_btn'):
            self.common_start_btn.setEnabled(True)
        if hasattr(self, 'common_stop_btn'):
            self.common_stop_btn.setEnabled(False)
        
        print("停止共同群聊任务")
    
    def start_personal_task(self):
        """开始不同群聊任务"""
        if self.personal_task_running:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "任务已在运行中！")
            return
        
        # 检查A/B账号是否已设置
        if not self.is_ab_accounts_ready():
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "请先设置A和B账号！")
            return
        
        # 更新任务状态
        self.personal_task_running = True
        
        # 更新按钮状态
        if hasattr(self, 'personal_start_btn'):
            self.personal_start_btn.setEnabled(False)
        if hasattr(self, 'personal_stop_btn'):
            self.personal_stop_btn.setEnabled(True)
        
        # 获取任务参数
        script = self.personal_sender_combo.currentText()
        group = self.personal_device_combo.currentText()
        
        # 获取A/B账号信息 - 使用user_name作为wxid参数
        account_a_name = self.account_a.get('user_name')  # 使用user_name字段
        account_b_name = self.account_b.get('user_name')  # 使用user_name字段
        
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(
            self, 
            "开始AB互打任务", 
            f"已开始AB互打任务\n"
            f"A账号: {account_a_name}\n"
            f"B账号: {account_b_name}\n"
            f"选择话术: {script}\n"
            f"选择分组: {group}"
        )
        print(f"开始AB互打任务: A={account_a_name}, B={account_b_name}")
    
    def stop_personal_task(self):
        """停止不同群聊任务"""
        if not self.personal_task_running:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "警告", "没有正在运行的任务！")
            return
        
        # 更新任务状态
        self.personal_task_running = False
        
        # 更新按钮状态
        if hasattr(self, 'personal_start_btn'):
            self.personal_start_btn.setEnabled(True)
        if hasattr(self, 'personal_stop_btn'):
            self.personal_stop_btn.setEnabled(False)
        
        from PyQt6.QtWidgets import QMessageBox
        QMessageBox.information(self, "停止任务", "不同群聊任务已停止")
        print("停止不同群聊任务")
    
    def start_queue_monitor(self):
        """启动队列监控定时器"""
        from PyQt6.QtCore import QTimer
        
        self.queue_timer = QTimer()
        self.queue_timer.timeout.connect(self.refresh_data)
        self.queue_timer.start(5000)  # 每5秒更新一次
        
        # 初始化数据
        self.setup_data()
        
        print("任务队列监控已启动")
    
    def stop_queue_monitor(self):
        """停止队列监控"""
        if hasattr(self, 'queue_timer'):
            self.queue_timer.stop()
        print("任务队列监控已停止")
    
    def refresh_data(self):
        """刷新数据"""
        # 刷新账号列表
        if hasattr(self, 'account_list'):
            self.refresh_account_list()
    
    def show_tab_content(self, tab_name):
        """显示指定的 tab 内容"""
        # 清除当前内容容器
        while self.content_container.layout().count():
            child = self.content_container.layout().takeAt(0)
            if child.widget():
                child.widget().setParent(None)
        
        # 显示新内容
        if tab_name == "ab":
            self.content_container.layout().addWidget(self.ab_page)
        elif tab_name == "template":
            self.content_container.layout().addWidget(self.template_page)
        
        self.current_tab = tab_name
    
    def show_ab_tab(self):
        """显示 AB 互打 tab"""
        self.show_tab_content("ab")
        self.update_tab_styles("ab")
    
    def show_template_tab(self):
        """显示话术模板 tab"""
        self.show_tab_content("template")
        self.update_tab_styles("template")
    
    def update_tab_styles(self, active_tab):
        """更新 tab 按钮样式"""
        # 重置所有按钮样式
        self.ab_tab_btn.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: #007bff;
                border: none;
                font-weight: bold;
                font-size: 14px;
                padding: 8px 16px;
            }
            QPushButton:hover {
                color: #0056b3;
                text-decoration: underline;
            }
        """)
        
        self.template_tab_btn.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: #007bff;
                border: none;
                font-weight: bold;
                font-size: 14px;
                padding: 8px 16px;
            }
            QPushButton:hover {
                color: #0056b3;
                text-decoration: underline;
            }
        """)
        
        # 突出显示当前选中的按钮
        if active_tab == "ab":
            self.ab_tab_btn.setStyleSheet("""
                QPushButton {
                    background-color: #007bff;
                    color: white;
                    border: none;
                    font-weight: bold;
                    font-size: 14px;
                    padding: 8px 16px;
                    border-radius: 4px;
                }
                QPushButton:hover {
                    background-color: #0056b3;
                }
            """)
        elif active_tab == "template":
            self.template_tab_btn.setStyleSheet("""
                QPushButton {
                    background-color: #007bff;
                    color: white;
                    border: none;
                    font-weight: bold;
                    font-size: 14px;
                    padding: 8px 16px;
                    border-radius: 4px;
                }
                QPushButton:hover {
                    background-color: #0056b3;
                }
            """) 
    
    def load_templates(self):
        """加载模板数据"""
        try:
            self.templates = db_manager.get_all_templates()
        except Exception as e:
            print(f"加载模板失败: {e}")
            self.templates = []
    
    def load_script_options(self, combo_box):
        """加载话术选项到下拉框"""
        combo_box.clear()
        combo_box.addItem("请选择话术")
        
        # 添加所有模板名称
        for template in self.templates:
            combo_box.addItem(template['name'])
    
    def refresh_script_combos(self):
        """刷新所有话术下拉框"""
        # 刷新共同群聊的话术下拉框
        if hasattr(self, 'common_sender_combo'):
            self.load_script_options(self.common_sender_combo)
            # 更新对应的分组选项
            current_template = self.common_sender_combo.currentText()
            self.on_sender_combo_changed(current_template, self.common_device_combo)
        
        # 刷新不同群聊的话术下拉框
        if hasattr(self, 'personal_sender_combo'):
            self.load_script_options(self.personal_sender_combo)
            # 更新对应的分组选项
            current_template = self.personal_sender_combo.currentText()
            self.on_sender_combo_changed(current_template, self.personal_device_combo)
    
    def on_sender_combo_changed(self, selected_template_name: str, device_combo: QComboBox):
        """处理话术选择变化，更新分组选项"""
        device_combo.clear()
        device_combo.addItem("请选择分组")
        
        if selected_template_name == "请选择话术":
            return
        
        # 查找选中的模板
        selected_template = None
        for template in self.templates:
            if template['name'] == selected_template_name:
                selected_template = template
                break
        
        if not selected_template:
            print(f"未找到模板: {selected_template_name}")
            return
        
        print(f"找到模板: {selected_template_name}")
        
        # 获取模板的所有分组（分组子集）
        all_groups = set()
        for dialogue in selected_template.get('dialogues', []):
            # 只处理启用了分组的对话
            if dialogue.get('use_groups', False):
                group_data = dialogue.get('group_data', {})
                if isinstance(group_data, dict) and group_data:
                    # 添加该对话中的所有分组名称
                        all_groups.update(group_data.keys())
                        print(f"从对话中找到分组: {list(group_data.keys())}")
                elif isinstance(group_data, str):
                    # 处理可能是JSON字符串的情况
                    try:
                        parsed_group_data = json.loads(group_data)
                        if isinstance(parsed_group_data, dict):
                            all_groups.update(parsed_group_data.keys())
                            print(f"从JSON字符串解析到分组: {list(parsed_group_data.keys())}")
                    except (json.JSONDecodeError, TypeError) as e:
                        print(f"解析分组数据失败: {e}")
                        continue
        
        # 添加分组选项
        if all_groups:
            # 按字母顺序排序分组名称
            sorted_groups = sorted(all_groups)
            for group_name in sorted_groups:
                device_combo.addItem(group_name)
            print(f"添加分组选项: {sorted_groups}")
            print(f"总共找到 {len(sorted_groups)} 个分组")
        else:
            device_combo.addItem("无分组")
            print("模板无分组")
    
    def add_template(self):
        """添加模板"""
        dialog = TemplateEditDialog(self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            if dialog.validate_input():
                template_data = dialog.get_template_data()
                if db_manager.add_template(template_data):
                    self.load_templates()  # 重新加载模板
                    self.refresh_template_table()
                    self.refresh_script_combos()  # 刷新话术下拉框
                    QMessageBox.information(self, "成功", "模板添加成功！")
                else:
                    QMessageBox.critical(self, "错误", "模板添加失败！")

    def edit_template(self, row):
        """编辑模板"""
        if 0 <= row < len(self.templates):
            template = self.templates[row]
            # 获取完整的模板数据
            full_template = db_manager.get_template_by_id(template['id'])
            if full_template:
                dialog = TemplateEditDialog(self, full_template)
                if dialog.exec() == QDialog.DialogCode.Accepted:
                    if dialog.validate_input():
                        template_data = dialog.get_template_data()
                        if db_manager.update_template(template['id'], template_data):
                            self.load_templates()  # 重新加载模板
                            self.refresh_template_table()
                            self.refresh_script_combos()  # 刷新话术下拉框
                            QMessageBox.information(self, "成功", "模板更新成功！")
                        else:
                            QMessageBox.critical(self, "错误", "模板更新失败！")
            else:
                QMessageBox.critical(self, "错误", "获取模板数据失败！")
    
    def delete_template(self, row):
        """删除模板"""
        if 0 <= row < len(self.templates):
            template = self.templates[row]
            reply = QMessageBox.question(self, "确认删除", 
                                       f"确定要删除模板 '{template['name']}' 吗？",
                                       QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.Yes:
                if db_manager.delete_template(template['id']):
                    self.load_templates()  # 重新加载模板
                    self.refresh_template_table()
                    self.refresh_script_combos()  # 刷新话术下拉框
                    QMessageBox.information(self, "成功", "模板删除成功！")
                else:
                    QMessageBox.critical(self, "错误", "模板删除失败！")

    def refresh_template_table(self):
        """刷新模板表格"""
        if hasattr(self, 'template_table'):
            self.template_table.setRowCount(0)
            for i, template in enumerate(self.templates):
                self.template_table.insertRow(i)
                self.template_table.setItem(i, 0, QTableWidgetItem(template['name']))
                self.template_table.setItem(i, 1, QTableWidgetItem(template.get('description', '')))
                self.template_table.setItem(i, 2, QTableWidgetItem(str(len(template.get('dialogues', [])))))
                self.template_table.setItem(i, 3, QTableWidgetItem(template['create_time']))
                
                # 创建操作按钮区域
                btn_widget = QWidget()
                btn_layout = QHBoxLayout(btn_widget)
                btn_layout.setContentsMargins(4, 4, 4, 4)  # 增加内边距
                btn_layout.setSpacing(5)
                
                # 编辑按钮
                edit_btn = QPushButton("编辑")
                StyleManager.set_button_style(edit_btn, "template-btn-edit")
                edit_btn.setMinimumHeight(30)  # 设置最小高度
                edit_btn.setMinimumWidth(60)   # 设置最小宽度
                edit_btn.clicked.connect(lambda checked, row=i: self.edit_template(row))
                
                # 删除按钮
                delete_btn = QPushButton("删除")
                StyleManager.set_button_style(delete_btn, "template-btn-delete")
                delete_btn.setMinimumHeight(30)  # 设置最小高度
                delete_btn.setMinimumWidth(60)   # 设置最小宽度
                delete_btn.clicked.connect(lambda checked, row=i: self.delete_template(row))
                
                btn_layout.addWidget(edit_btn)
                btn_layout.addWidget(delete_btn)
                btn_layout.addStretch()
                
                self.template_table.setCellWidget(i, 4, btn_widget)

    def create_template_table(self):
        """创建模板表格"""
        self.template_table = QTableWidget()
        self.template_table.setColumnCount(5)
        self.template_table.setHorizontalHeaderLabels(["模板名", "描述", "对话数", "时间", "操作"])
        
        # 设置表格样式
        self.template_table.setStyleSheet("""
            QTableWidget {
                background-color: #ffffff;
                border: 1px solid #cccccc;
                gridline-color: #e0e0e0;
                font-size: 12px;
            }
            QTableWidget::item {
                padding: 8px;
                border-bottom: 1px solid #e0e0e0;
            }
            QHeaderView::section {
                background-color: #f8f9fa;
                border: 1px solid #dee2e6;
                padding: 8px;
                font-weight: bold;
                font-size: 12px;
            }
        """)
        
        # 设置列宽
        header = self.template_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.Fixed)  # 模板名
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)  # 描述
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.Fixed)  # 对话数
        header.setSectionResizeMode(3, QHeaderView.ResizeMode.Fixed)  # 时间
        header.setSectionResizeMode(4, QHeaderView.ResizeMode.Fixed)  # 操作
        
        self.template_table.setColumnWidth(0, 150)  # 模板名
        self.template_table.setColumnWidth(2, 80)   # 对话数
        self.template_table.setColumnWidth(3, 150)  # 时间
        self.template_table.setColumnWidth(4, 180)  # 操作 - 增加宽度以适应按钮
        
        # 设置表格属性：选中整行
        self.template_table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
        self.template_table.setAlternatingRowColors(True)
        self.template_table.setWordWrap(True)
        
        # 设置行高以适应按钮
        self.template_table.verticalHeader().setDefaultSectionSize(50)
        self.template_table.verticalHeader().setMinimumSectionSize(40)
        
        return self.template_table
    
class TemplateEditDialog(QDialog):
    """模板编辑对话框"""
    
    def __init__(self, parent=None, template_data=None):
        super().__init__(parent)
        self.template_data = template_data
        self.dialogues = template_data.get('dialogues', []) if template_data else []
        
        if template_data:
            self.setWindowTitle("编辑话术模板")
        else:
            self.setWindowTitle("添加话术模板")
        
        self.setFixedSize(800, 600)
        self.setup_ui()
        
        if template_data:
            self.load_template_data()
        
    def setup_ui(self):
        """设置对话框UI"""
        layout = QVBoxLayout(self)
        layout.setSpacing(10)  # 减少间距
        
        # 表单布局
        form_layout = QFormLayout()
        form_layout.setSpacing(8)  # 减少间距
        
        # 基本信息区域
        basic_group = QFrame()
        StyleManager.set_frame_style(basic_group, "basic-group")
        basic_layout = QVBoxLayout(basic_group)
        
        # 模板名称
        name_layout = QHBoxLayout()
        name_label = QLabel("模板名称:")
        self.name_edit = QLineEdit()
        self.name_edit.setPlaceholderText("请输入模板名称")
        name_layout.addWidget(name_label)
        name_layout.addWidget(self.name_edit)
        basic_layout.addLayout(name_layout)
        
        # 模板描述
        desc_layout = QHBoxLayout()
        desc_label = QLabel("模板描述:")
        self.desc_edit = QTextEdit()
        self.desc_edit.setPlaceholderText("请输入模板描述（可选）")
        self.desc_edit.setMaximumHeight(60)
        desc_layout.addWidget(desc_label)
        desc_layout.addWidget(self.desc_edit)
        basic_layout.addLayout(desc_layout)
        
        layout.addWidget(basic_group)
        
        # 对话编辑区域
        dialogue_group = QFrame()
        StyleManager.set_frame_style(dialogue_group, "dialogue-group")
        dialogue_layout = QVBoxLayout(dialogue_group)
        
        # 对话标题
        dialogue_title = QLabel("对话内容")
        StyleManager.set_label_style(dialogue_title, "dialogue-title")
        dialogue_layout.addWidget(dialogue_title)
        
        # 对话列表
        self.dialogue_list = QListWidget()
        self.dialogue_list.setMaximumHeight(300)
        dialogue_layout.addWidget(self.dialogue_list)
        
        # 对话操作按钮
        dialogue_btn_layout = QHBoxLayout()
        
        self.add_dialogue_btn = QPushButton("添加对话")
        self.add_dialogue_btn.clicked.connect(self.add_dialogue)
        self.add_dialogue_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        
        self.edit_dialogue_btn = QPushButton("编辑对话")
        self.edit_dialogue_btn.clicked.connect(self.edit_dialogue)
        self.edit_dialogue_btn.setStyleSheet("""
            QPushButton {
                background-color: #17a2b8;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #138496;
            }
        """)
        
        self.delete_dialogue_btn = QPushButton("删除对话")
        self.delete_dialogue_btn.clicked.connect(self.delete_dialogue)
        self.delete_dialogue_btn.setStyleSheet("""
            QPushButton {
                background-color: #dc3545;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #c82333;
            }
        """)
        
        self.move_up_btn = QPushButton("上移")
        self.move_up_btn.clicked.connect(self.move_dialogue_up)
        self.move_up_btn.setStyleSheet("""
            QPushButton {
                background-color: #6c757d;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #5a6268;
            }
        """)
        
        self.move_down_btn = QPushButton("下移")
        self.move_down_btn.clicked.connect(self.move_dialogue_down)
        self.move_down_btn.setStyleSheet("""
            QPushButton {
                background-color: #6c757d;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #5a6268;
            }
        """)
        
        dialogue_btn_layout.addWidget(self.add_dialogue_btn)
        dialogue_btn_layout.addWidget(self.edit_dialogue_btn)
        dialogue_btn_layout.addWidget(self.delete_dialogue_btn)
        dialogue_btn_layout.addWidget(self.move_up_btn)
        dialogue_btn_layout.addWidget(self.move_down_btn)
        dialogue_btn_layout.addStretch()
        
        dialogue_layout.addLayout(dialogue_btn_layout)
        layout.addWidget(dialogue_group)
        
        # 按钮区域
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        
        # 确定按钮
        ok_btn = QPushButton("确定")
        ok_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 8px 16px;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        ok_btn.clicked.connect(self.accept)
        
        # 取消按钮
        cancel_btn = QPushButton("取消")
        cancel_btn.setStyleSheet("""
            QPushButton {
                background-color: #6c757d;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 8px 16px;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #5a6268;
            }
        """)
        cancel_btn.clicked.connect(self.reject)
        
        button_layout.addWidget(ok_btn)
        button_layout.addWidget(cancel_btn)
        layout.addLayout(button_layout)
        
        # 刷新对话列表
        self.refresh_dialogue_list()
    
    def refresh_dialogue_list(self):
        """刷新对话列表"""
        self.dialogue_list.clear()
        for i, dialogue in enumerate(self.dialogues):
            speaker = dialogue['speaker']
            msg_type = dialogue['message_type']
            use_groups = dialogue.get('use_groups', False)
            group_data = dialogue.get('group_data', {})

            # 统一初始化
            content = dialogue.get('content', '')
            group_display = ""

            if use_groups and group_data:
                # 启用分组时，显示分组信息
                group_count = len(group_data)
                group_names = list(group_data.keys())
                if group_count == 1:
                    preview = f"[分组: {group_names[0]}]"
                elif group_count <= 3:
                    preview = f"[分组: {', '.join(group_names)}]"
                else:
                    preview = f"[分组: {group_names[0]}等{group_count}个]"
                group_display = f" (分组:{group_count}个)"
            else:
                # 未启用分组时，按消息类型生成预览
                if msg_type == 'text':
                    preview = content[:30] + "..." if len(content) > 30 else content
                elif msg_type == 'link':
                    preview = f"[链接] {content[:30]}..." if content else "[链接]"
                elif msg_type == 'voice':
                    preview = "[语音消息]"
                elif msg_type == 'image':
                    preview = "[图片消息]"
                else:
                    preview = "[未知类型]"
            
            item_text = f"{i+1}. {speaker}{group_display}: {preview}"
            item = QListWidgetItem(item_text)
            item.setData(Qt.ItemDataRole.UserRole, dialogue)
            self.dialogue_list.addItem(item)
    
    def add_dialogue(self):
        """添加对话"""
        dialogue_dialog = DialogueEditDialog(self)
        if dialogue_dialog.exec() == QDialog.DialogCode.Accepted:
            dialogue_data = dialogue_dialog.get_dialogue_data()
            if dialogue_data:
                self.dialogues.append(dialogue_data)
                self.refresh_dialogue_list()
    
    def edit_dialogue(self):
        """编辑对话"""
        current_row = self.dialogue_list.currentRow()
        if current_row >= 0 and current_row < len(self.dialogues):
            dialogue_data = self.dialogues[current_row]
            dialogue_dialog = DialogueEditDialog(self, dialogue_data)
            if dialogue_dialog.exec() == QDialog.DialogCode.Accepted:
                new_dialogue_data = dialogue_dialog.get_dialogue_data()
                if new_dialogue_data:
                    self.dialogues[current_row] = new_dialogue_data
                    self.refresh_dialogue_list()
        else:
            QMessageBox.warning(self, "警告", "请先选择要编辑的对话！")
    
    def delete_dialogue(self):
        """删除对话"""
        current_row = self.dialogue_list.currentRow()
        if current_row >= 0 and current_row < len(self.dialogues):
            reply = QMessageBox.question(self, "确认删除", 
                                       "确定要删除这个对话吗？",
                                       QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.Yes:
                del self.dialogues[current_row]
                self.refresh_dialogue_list()
        else:
            QMessageBox.warning(self, "警告", "请先选择要删除的对话！")
    
    def move_dialogue_up(self):
        """上移对话"""
        current_row = self.dialogue_list.currentRow()
        if current_row > 0 and current_row < len(self.dialogues):
            self.dialogues[current_row], self.dialogues[current_row-1] = \
                self.dialogues[current_row-1], self.dialogues[current_row]
            self.refresh_dialogue_list()
            self.dialogue_list.setCurrentRow(current_row-1)
    
    def move_dialogue_down(self):
        """下移对话"""
        current_row = self.dialogue_list.currentRow()
        if current_row >= 0 and current_row < len(self.dialogues) - 1:
            self.dialogues[current_row], self.dialogues[current_row+1] = \
                self.dialogues[current_row+1], self.dialogues[current_row]
            self.refresh_dialogue_list()
            self.dialogue_list.setCurrentRow(current_row+1)
    
    def load_template_data(self):
        """加载模板数据"""
        if self.template_data:
            self.name_edit.setText(self.template_data.get('name', ''))
            self.desc_edit.setPlainText(self.template_data.get('description', ''))
            self.dialogues = self.template_data.get('dialogues', [])
            self.refresh_dialogue_list()
    
    def get_template_data(self):
        """获取模板数据"""
        return {
            "name": self.name_edit.text().strip(),
            "description": self.desc_edit.toPlainText().strip(),
            "dialogues": self.dialogues,
            "create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }
    
    def on_type_changed(self, type_text):
        """类型变化时的处理"""
        # 隐藏所有内容区域
        self.content_edit.setVisible(True)
        self.voice_frame.setVisible(False)
        self.image_frame.setVisible(False)
        
        # 分组功能只在图片和链接时显示
        if type_text in ["图片", "链接"]:
            self.groups_label.setVisible(True)
            self.use_groups_checkbox.setVisible(True)
            self.groups_frame.setVisible(self.use_groups_checkbox.isChecked())
            
            # 如果启用了分组，隐藏消息内容区域
            if self.use_groups_checkbox.isChecked():
                self.content_widget.setVisible(False)
            else:
                self.content_widget.setVisible(True)
        else:
            self.groups_label.setVisible(False)
            self.use_groups_checkbox.setVisible(False)
            self.groups_frame.setVisible(False)
            
            # 非分组类型时，显示消息内容区域
            self.content_widget.setVisible(True)
        
        if type_text == "文本":
            self.content_edit.setPlaceholderText("请输入文本内容，例如：您好，这是一条测试消息")
        elif type_text == "链接":
            self.content_edit.setPlaceholderText("请输入链接内容，例如：https://example.com 或 点击查看详情：https://example.com")
        elif type_text == "语音":
            self.content_edit.setVisible(False)
            self.voice_frame.setVisible(True)
            self.content_edit.setPlaceholderText("语音录制区域")
        elif type_text == "图片":
            self.content_edit.setVisible(False)
            self.image_frame.setVisible(True)
            self.content_edit.setPlaceholderText("图片选择区域")
    
    def toggle_recording(self):
        """切换录音状态"""
        if not self.recording:
            self.start_recording()
        else:
            self.stop_recording()
    
    def start_recording(self):
        """开始录音"""
        try:
            # 创建临时录音文件
            import tempfile
            self.temp_audio_file = tempfile.NamedTemporaryFile(suffix='.mp3', delete=False)
            self.temp_audio_path = self.temp_audio_file.name
            self.temp_audio_file.close()
            
            # 初始化录音器
            self.recorder = QMediaRecorder()
            self.capture_session = QMediaCaptureSession()
            self.audio_input = QAudioInput()
            
            # 设置录音会话
            self.capture_session.setRecorder(self.recorder)
            self.capture_session.setAudioInput(self.audio_input)
            
            # 设置录音格式
            format = QMediaFormat()
            format.setFileFormat(QMediaFormat.FileFormat.MP3)
            self.recorder.setMediaFormat(format)
            
            # 设置输出文件
            self.recorder.setOutputLocation(QUrl.fromLocalFile(self.temp_audio_path))
            
            # 开始录音
            self.recorder.record()
            self.recording = True
            self.record_btn.setText("停止录音")
            self.record_btn.setStyleSheet("""
                QPushButton {
                    background-color: #dc3545;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-weight: bold;
                    padding: 6px 12px;  /* 减少内边距 */
                    font-size: 12px;  /* 减少字体 */
                }
                QPushButton:hover {
                    background-color: #c82333;
                }
            """)
            
            # 启动计时器
            self.record_seconds = 0
            self.record_timer.start(1000)  # 每秒更新一次
            self.record_progress.setVisible(True)
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"启动录音失败：{str(e)}")
    
    def stop_recording(self):
        """停止录音"""
        try:
            if self.recorder:
                self.recorder.stop()
                self.recording = False
                self.record_btn.setText("开始录音")
                self.record_btn.setStyleSheet("""
                    QPushButton {
                        background-color: #dc3545;
                        color: white;
                        border: none;
                        border-radius: 4px;
                        font-weight: bold;
                        padding: 6px 12px;  /* 减少内边距 */
                        font-size: 12px;  /* 减少字体 */
                    }
                    QPushButton:hover {
                        background-color: #c82333;
                    }
                """)
                
                # 停止计时器
                self.record_timer.stop()
                self.record_progress.setVisible(False)
                
                # 释放录音器资源
                self.recorder = None
                self.capture_session = None
                self.audio_input = None
                
                # 读取录音文件并转换为base64
                if hasattr(self, 'temp_audio_path') and os.path.exists(self.temp_audio_path):
                    try:
                        with open(self.temp_audio_path, 'rb') as f:
                            audio_data = f.read()
                            self.recorded_audio_data = base64.b64encode(audio_data).decode('utf-8')
                        
                            # 启用播放按钮
                            self.play_btn.setEnabled(True)
                        
                        QMessageBox.information(self, "成功", f"录音完成，时长：{self.record_seconds}秒")
                    except Exception as e:
                        QMessageBox.warning(self, "警告", f"读取录音文件失败：{str(e)}")
                    finally:
                        # 延迟删除临时文件，避免文件占用冲突
                        QTimer.singleShot(200, lambda: self.delete_temp_file(self.temp_audio_path))
                else:
                    QMessageBox.warning(self, "警告", "录音文件未找到")
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"停止录音失败：{str(e)}")
    
    def update_record_time(self):
        """更新录音时间"""
        self.record_seconds += 1
        self.record_time_label.setText(f"录音时长: {self.record_seconds}秒")
        self.record_progress.setValue(self.record_seconds)
        
        # 达到60秒自动停止
        if self.record_seconds >= 60:
            self.stop_recording()
    
    def play_recording(self):
        """播放录音"""
        print(f"[DEBUG] TemplateEditDialog - 开始播放录音")
        if not self.recorded_audio_data:
            print(f"[DEBUG] TemplateEditDialog - 没有录音数据")
            QMessageBox.warning(self, "警告", "没有可播放的录音！")
            return
        
        try:
            # 创建临时文件用于播放
            import tempfile
            temp_file = tempfile.NamedTemporaryFile(suffix='.mp3', delete=False)
            temp_path = temp_file.name
            temp_file.close()
            print(f"[DEBUG] TemplateEditDialog - 临时播放文件创建成功: {temp_path}")
            
            # 将base64数据写入临时文件
            audio_data = base64.b64decode(self.recorded_audio_data)
            print(f"[DEBUG] TemplateEditDialog - 解码后的音频数据大小: {len(audio_data)} 字节")
            
            with open(temp_path, 'wb') as f:
                f.write(audio_data)
            print(f"[DEBUG] TemplateEditDialog - 音频数据写入临时文件成功")
            
            # 检查文件是否存在和大小
            if os.path.exists(temp_path):
                file_size = os.path.getsize(temp_path)
                print(f"[DEBUG] TemplateEditDialog - 临时文件大小: {file_size} 字节")
            else:
                print(f"[DEBUG] TemplateEditDialog - 临时文件不存在!")
                return
            
            # 创建播放器并播放
            if not self.audio_player:
                self.audio_player = QMediaPlayer()
                print(f"[DEBUG] TemplateEditDialog - 创建新的QMediaPlayer实例")
            else:
                print(f"[DEBUG] TemplateEditDialog - 使用现有的QMediaPlayer实例")
            
            # 设置音频输出
            from PyQt6.QtMultimedia import QAudioOutput
            if not hasattr(self, 'audio_output'):
                self.audio_output = QAudioOutput()
                self.audio_player.setAudioOutput(self.audio_output)
                print(f"[DEBUG] TemplateEditDialog - 设置音频输出")
            
            # 设置音量
            self.audio_output.setVolume(1.0)  # 设置最大音量
            print(f"[DEBUG] TemplateEditDialog - 设置音量: {self.audio_output.volume()}")
            
            # 检查音频输出设备
            from PyQt6.QtMultimedia import QMediaDevices
            audio_devices = QMediaDevices.audioOutputs()
            print(f"[DEBUG] TemplateEditDialog - 可用音频输出设备数量: {len(audio_devices)}")
            for i, device in enumerate(audio_devices):
                print(f"[DEBUG] TemplateEditDialog - 音频设备 {i}: {device.description()}")
            
            # 设置默认音频输出设备
            if audio_devices:
                self.audio_output.setDevice(audio_devices[0])
                print(f"[DEBUG] TemplateEditDialog - 设置音频设备: {audio_devices[0].description()}")
            
            # 设置播放源
            self.audio_player.setSource(QUrl.fromLocalFile(temp_path))
            print(f"[DEBUG] TemplateEditDialog - 设置播放源: {temp_path}")
            
            # 连接错误信号
            self.audio_player.errorOccurred.connect(self.on_playback_error)
            
            # 连接播放状态变化信号
            self.audio_player.mediaStatusChanged.connect(self.on_media_status_changed)
            
            # 开始播放
            self.audio_player.play()
            print(f"[DEBUG] TemplateEditDialog - 开始播放")
            
            # 检查播放状态
            QTimer.singleShot(100, self.check_playback_status)
            
            # 播放完成后删除临时文件
            self.audio_player.mediaStatusChanged.connect(
                lambda status: self.on_playback_finished(status, temp_path)
            )
            
            # 更新按钮状态
            self.play_btn.setText("停止播放")
            self.play_btn.setStyleSheet("""
                QPushButton {
                    background-color: #ffc107;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-weight: bold;
                    padding: 6px 12px;
                    font-size: 12px;
                }
                QPushButton:hover {
                    background-color: #e0a800;
                }
            """)
            self.play_btn.clicked.disconnect()
            self.play_btn.clicked.connect(self.stop_playback)
            
        except Exception as e:
            print(f"[DEBUG] TemplateEditDialog - 播放录音失败: {str(e)}")
            QMessageBox.critical(self, "错误", f"播放录音失败：{str(e)}")
    
    def try_play_wav_format(self):
        """尝试使用WAV格式播放"""
        print(f"[DEBUG] TemplateEditDialog - 尝试使用WAV格式播放")
        try:
            # 创建WAV格式的临时文件
            import tempfile
            temp_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
            temp_path = temp_file.name
            temp_file.close()
            
            # 将base64数据写入临时文件
            audio_data = base64.b64decode(self.recorded_audio_data)
            with open(temp_path, 'wb') as f:
                f.write(audio_data)
            
            # 设置播放源为WAV文件
            self.audio_player.setSource(QUrl.fromLocalFile(temp_path))
            self.audio_player.play()
            print(f"[DEBUG] TemplateEditDialog - WAV格式播放开始")
            
        except Exception as e:
            print(f"[DEBUG] TemplateEditDialog - WAV格式播放失败: {str(e)}")
            QMessageBox.warning(self, "警告", "WAV格式播放也失败，请检查音频文件")
    
    def on_playback_error(self, error, error_string):
        """播放错误回调"""
        print(f"[DEBUG] TemplateEditDialog - 播放错误: {error}, {error_string}")
        
        # 如果是格式错误，尝试WAV格式
        if "format" in error_string.lower() or "unsupported" in error_string.lower():
            print(f"[DEBUG] TemplateEditDialog - 检测到格式错误，尝试WAV格式")
            self.try_play_wav_format()
        else:
            QMessageBox.warning(self, "播放错误", f"播放失败：{error_string}")
    
    def on_media_status_changed(self, status):
        """媒体状态变化回调"""
        status_names = {
            QMediaPlayer.MediaStatus.NoMedia: "无媒体",
            QMediaPlayer.MediaStatus.LoadingMedia: "加载中",
            QMediaPlayer.MediaStatus.LoadedMedia: "已加载",
            QMediaPlayer.MediaStatus.StalledMedia: "停滞",
            QMediaPlayer.MediaStatus.BufferingMedia: "缓冲中",
            QMediaPlayer.MediaStatus.BufferedMedia: "已缓冲",
            QMediaPlayer.MediaStatus.EndOfMedia: "播放结束",
            QMediaPlayer.MediaStatus.InvalidMedia: "无效媒体"
        }
        status_name = status_names.get(status, f"未知状态({status})")
        print(f"[DEBUG] TemplateEditDialog - 媒体状态变化: {status_name}")
        
        if status == QMediaPlayer.MediaStatus.LoadedMedia:
            print(f"[DEBUG] TemplateEditDialog - 媒体加载完成，准备播放")
        elif status == QMediaPlayer.MediaStatus.EndOfMedia:
            print(f"[DEBUG] TemplateEditDialog - 播放完成")
        elif status == QMediaPlayer.MediaStatus.InvalidMedia:
            print(f"[DEBUG] TemplateEditDialog - 无效媒体格式")
            QMessageBox.warning(self, "播放错误", "不支持的音频格式")
    
    def check_playback_status(self):
        """检查播放状态"""
        if self.audio_player:
            playback_state = self.audio_player.playbackState()
            state_names = {
                QMediaPlayer.PlaybackState.StoppedState: "已停止",
                QMediaPlayer.PlaybackState.PlayingState: "播放中",
                QMediaPlayer.PlaybackState.PausedState: "已暂停"
            }
            state_name = state_names.get(playback_state, f"未知状态({playback_state})")
            print(f"[DEBUG] TemplateEditDialog - 播放状态: {state_name}")
            
            # 检查是否有错误
            error = self.audio_player.error()
            if error != QMediaPlayer.Error.NoError:
                print(f"[DEBUG] TemplateEditDialog - 播放错误: {self.audio_player.errorString()}")
            else:
                print(f"[DEBUG] TemplateEditDialog - 播放正常")
    
    def stop_playback(self):
        """停止播放"""
        if self.audio_player:
            self.audio_player.stop()
        
        # 恢复播放按钮状态
        self.play_btn.setText("播放录音")
        self.play_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        self.play_btn.clicked.disconnect()
        self.play_btn.clicked.connect(self.play_recording)
    
    def on_playback_finished(self, status, temp_path):
        """播放完成回调"""
        if status == QMediaPlayer.MediaStatus.EndOfMedia:
            # 延迟删除临时文件，避免文件占用冲突
            QTimer.singleShot(200, lambda: self.delete_temp_file(temp_path))
            
            # 恢复播放按钮状态
            self.stop_playback()
    
    def delete_temp_file(self, file_path):
        """安全删除临时文件"""
        try:
            if os.path.exists(file_path):
                os.unlink(file_path)
        except:
            pass  # 忽略删除失败的错误
    
    def select_image(self):
        """选择图片"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择图片", "", "图片文件 (*.jpg *.jpeg *.png *.gif *.bmp);;所有文件 (*)"
        )
        if file_path:
            try:
                # 读取图片文件并转换为base64
                with open(file_path, 'rb') as f:
                    image_data = f.read()
                    self.image_base64 = base64.b64encode(image_data).decode('utf-8')
                
                self.selected_image_path = file_path
                file_size = len(image_data) / 1024  # KB
                self.image_info_label.setText(f"已选择: {os.path.basename(file_path)} ({file_size:.1f} KB)")
                
            except Exception as e:
                QMessageBox.critical(self, "错误", f"读取图片失败：{str(e)}")
    
    def validate_input(self):
        """验证输入"""
        if not self.name_edit.text().strip():
            QMessageBox.warning(self, "警告", "请输入模板名称！")
            return False
        
        if not self.dialogues:
            QMessageBox.warning(self, "警告", "请至少添加一个对话！")
            return False
        
        return True


class DialogueEditDialog(QDialog):
    """对话编辑对话框"""
    
    def __init__(self, parent=None, dialogue_data=None):
        super().__init__(parent)
        self.dialogue_data = dialogue_data
        
        # 初始化分组数据
        self.group_data = {}
        
        if dialogue_data:
            self.setWindowTitle("编辑对话")
        else:
            self.setWindowTitle("添加对话")
        
        # 允许对话框可调整大小，避免控件拥挤/重叠
        self.setMinimumSize(500, 400)
        self.setup_ui()
        
        if dialogue_data:
            self.load_dialogue_data()
    
    def setup_ui(self):
        """设置对话框UI"""
        layout = QVBoxLayout(self)
        layout.setSpacing(10)  # 减少间距
        
        # 表单布局
        form_layout = QFormLayout()
        form_layout.setSpacing(8)  # 减少间距
        
        # 说话者选择
        self.speaker_combo = QComboBox()
        self.speaker_combo.addItems(["A", "B"])
        form_layout.addRow("说话者:", self.speaker_combo)
        
        # 消息类型选择
        self.type_combo = QComboBox()
        self.type_combo.addItems(["文本", "链接", "语音", "图片"])
        form_layout.addRow("消息类型:", self.type_combo)
        
        # 分组设置（手动布局，可以控制标签显示）
        self.groups_label = QLabel("分组设置:")
        self.use_groups_checkbox = QCheckBox("启用分组")
        self.use_groups_checkbox.setVisible(False)
        self.groups_label.setVisible(False)
        
        # 创建分组设置的布局
        groups_setting_layout = QHBoxLayout()
        groups_setting_layout.addWidget(self.groups_label)
        groups_setting_layout.addWidget(self.use_groups_checkbox)
        groups_setting_layout.addStretch()
        
        # 将分组设置添加到主布局
        layout.addLayout(groups_setting_layout)
        
        # 分组管理区域
        self.groups_frame = QFrame()
        self.groups_frame.setVisible(False)
        StyleManager.set_frame_style(self.groups_frame, "groups-frame")  # 减少内边距
        groups_layout = QVBoxLayout(self.groups_frame)
        groups_layout.setSpacing(6)  # 减少间距
        
        # 分组标题
        groups_title = QLabel("分组内容")
        StyleManager.set_label_style(groups_title, "groups-title")  # 减少间距
        groups_layout.addWidget(groups_title)
        
        # 分组列表
        self.groups_list = QListWidget()
        # 让列表高度随布局伸缩，开启滚动后无需设置固定高度
        
        # 设置列表样式
        self.groups_list.setStyleSheet("""
            QListWidget {
                background-color: #ffffff;
                border: 1px solid #cccccc;
                border-radius: 4px;
                font-size: 13px;
                padding: 5px;
            }
            QListWidget::item {
                background-color: #f8f9fa;
                border: 1px solid #e0e0e0;
                border-radius: 4px;
                margin: 1px;  /* 减少边距 */
                padding: 6px;  /* 减少内边距 */
                min-height: 35px;  /* 减少最小高度 */
            }
            QListWidget::item:selected {
                background-color: #007bff;
                color: white;
            }
            QListWidget::item:hover {
                background-color: #e3f2fd;
            }
        """)
        
        # 设置列表属性
        self.groups_list.setSpacing(3)  # 项目间距
        # 强制显示竖直滚动条，避免内容较多时出现与按钮重叠的视觉问题
        self.groups_list.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
        
        # 连接双击信号
        self.groups_list.itemDoubleClicked.connect(self.on_group_item_double_clicked)
        
        # 将列表放入容器，确保布局计算正确
        groups_layout.addWidget(self.groups_list, 1)
        
        # 分组操作按钮
        groups_btn_layout = QHBoxLayout()
        groups_btn_layout.setSpacing(4)  # 减少按钮间距
        
        self.add_group_btn = QPushButton("添加分组")
        self.add_group_btn.clicked.connect(self.add_group)
        self.add_group_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 3px;
                font-weight: bold;
                padding: 3px 6px;  /* 减少内边距 */
                font-size: 10px;  /* 减少字体 */
                min-height: 20px;  /* 减少最小高度 */
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        
        self.edit_group_btn = QPushButton("编辑分组")
        self.edit_group_btn.clicked.connect(self.edit_group)
        self.edit_group_btn.setStyleSheet("""
            QPushButton {
                background-color: #17a2b8;
                color: white;
                border: none;
                border-radius: 3px;
                font-weight: bold;
                padding: 3px 6px;  /* 减少内边距 */
                font-size: 10px;  /* 减少字体 */
                min-height: 20px;  /* 减少最小高度 */
            }
            QPushButton:hover {
                background-color: #138496;
            }
        """)
        
        self.delete_group_btn = QPushButton("删除分组")
        self.delete_group_btn.clicked.connect(self.delete_group)
        self.delete_group_btn.setStyleSheet("""
            QPushButton {
                background-color: #dc3545;
                color: white;
                border: none;
                border-radius: 3px;
                font-weight: bold;
                padding: 3px 6px;  /* 减少内边距 */
                font-size: 10px;  /* 减少字体 */
                min-height: 20px;  /* 减少最小高度 */
            }
            QPushButton:hover {
                background-color: #c82333;
            }
        """)
        
        groups_btn_layout.addWidget(self.add_group_btn)
        groups_btn_layout.addWidget(self.edit_group_btn)
        groups_btn_layout.addWidget(self.delete_group_btn)
        groups_btn_layout.addStretch()

        # 将按钮条作为固定高度控件添加，避免与列表重叠
        groups_layout.addLayout(groups_btn_layout, 0)
        
        # 将分组管理区域添加到主布局
        layout.addWidget(self.groups_frame)
        
        # 消息内容区域
        content_layout = QVBoxLayout()
        
        # 文本/链接内容输入
        self.content_edit = QTextEdit()
        self.content_edit.setMaximumHeight(100)  # 减少高度
        content_layout.addWidget(self.content_edit)
        
        # 语音录制区域
        self.voice_frame = QWidget()
        voice_layout = QVBoxLayout(self.voice_frame)
        
        # 录音控制按钮
        voice_control_layout = QHBoxLayout()
        self.record_btn = QPushButton("开始录音")
        self.record_btn.setStyleSheet("""
            QPushButton {
                background-color: #dc3545;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;  /* 减少内边距 */
                font-size: 12px;  /* 减少字体 */
            }
            QPushButton:hover {
                background-color: #c82333;
            }
        """)
        self.record_btn.clicked.connect(self.toggle_recording)
        voice_control_layout.addWidget(self.record_btn)
        
        # 播放按钮
        self.play_btn = QPushButton("播放录音")
        self.play_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;  /* 减少内边距 */
                font-size: 12px;  /* 减少字体 */
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        self.play_btn.clicked.connect(self.play_recording)
        self.play_btn.setEnabled(False)  # 初始状态禁用
        voice_control_layout.addWidget(self.play_btn)
        
        # 录音时长显示
        self.record_time_label = QLabel("录音时长: 0秒")
        StyleManager.set_label_style(self.record_time_label, "record-time")  # 减少字体
        
        voice_control_layout.addWidget(self.record_time_label)
        
        voice_control_layout.addStretch()
        voice_layout.addLayout(voice_control_layout)
        
        # 录音进度条
        self.record_progress = QProgressBar()
        self.record_progress.setMaximum(60)  # 最大60秒
        self.record_progress.setVisible(False)
        self.record_progress.setMaximumHeight(12)  # 减少进度条高度
        voice_layout.addWidget(self.record_progress)
        
        self.voice_frame.setVisible(False)
        content_layout.addWidget(self.voice_frame)
        
        # 图片选择区域
        self.image_frame = QWidget()
        image_layout = QVBoxLayout(self.image_frame)
        
        # 图片选择按钮
        self.select_image_btn = QPushButton("选择图片")
        self.select_image_btn.setStyleSheet("""
            QPushButton {
                background-color: #17a2b8;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;  /* 减少内边距 */
                font-size: 12px;  /* 减少字体 */
            }
            QPushButton:hover {
                background-color: #138496;
            }
        """)
        self.select_image_btn.clicked.connect(self.select_image)
        image_layout.addWidget(self.select_image_btn)
        
        # 图片信息显示
        self.image_info_label = QLabel("未选择图片")
        StyleManager.set_label_style(self.image_info_label, "image-info")  # 减少字体
        image_layout.addWidget(self.image_info_label)
        
        self.image_frame.setVisible(False)
        content_layout.addWidget(self.image_frame)
        
        # 消息内容区域（手动布局，可以控制显示）
        self.content_widget = QWidget()
        self.content_widget.setLayout(content_layout)
        
        # 将消息内容区域添加到主布局
        layout.addWidget(self.content_widget)
        
        layout.addLayout(form_layout)
        
        # 连接类型变化信号
        self.type_combo.currentTextChanged.connect(self.on_type_changed)
        
        # 录音相关变量
        self.recorder = None
        self.audio_input = None
        self.recording = False
        self.record_timer = QTimer()
        self.record_timer.timeout.connect(self.update_record_time)
        self.record_seconds = 0
        self.recorded_audio_data = None
        self.audio_player = None
        
        # 图片相关变量
        self.selected_image_path = None
        self.image_base64 = None
        
        # 设置默认提示文本
        self.on_type_changed("文本")
        
        # 连接分组复选框信号（仅一次）
        self.use_groups_checkbox.toggled.connect(self.on_groups_toggled)
        
        # 按钮区域
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        
        # 确定按钮
        ok_btn = QPushButton("确定")
        ok_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 8px 16px;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        ok_btn.clicked.connect(self.accept)
        
        # 取消按钮
        cancel_btn = QPushButton("取消")
        cancel_btn.setStyleSheet("""
            QPushButton {
                background-color: #6c757d;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 8px 16px;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #5a6268;
            }
        """)
        cancel_btn.clicked.connect(self.reject)
        
        button_layout.addWidget(ok_btn)
        button_layout.addWidget(cancel_btn)
        layout.addLayout(button_layout)
    
    def on_type_changed(self, type_text):
        """类型变化时的处理"""
        # 隐藏所有内容区域
        self.content_edit.setVisible(True)
        self.voice_frame.setVisible(False)
        self.image_frame.setVisible(False)
        
        # 分组功能只在图片和链接时显示
        if type_text in ["图片", "链接"]:
            self.groups_label.setVisible(True)
            self.use_groups_checkbox.setVisible(True)
            self.groups_frame.setVisible(self.use_groups_checkbox.isChecked())
            
            # 如果启用了分组，隐藏消息内容区域
            if self.use_groups_checkbox.isChecked():
                self.content_widget.setVisible(False)
            else:
                self.content_widget.setVisible(True)
        else:
            self.groups_label.setVisible(False)
            self.use_groups_checkbox.setVisible(False)
            self.groups_frame.setVisible(False)
            
            # 非分组类型时，显示消息内容区域
            self.content_widget.setVisible(True)
        
        if type_text == "文本":
            self.content_edit.setPlaceholderText("请输入文本内容，例如：您好，这是一条测试消息")
        elif type_text == "链接":
            self.content_edit.setPlaceholderText("请输入链接内容，例如：https://example.com 或 点击查看详情：https://example.com")
            # 为链接类型添加专门的编辑按钮
            if not hasattr(self, 'link_edit_btn'):
                self.link_edit_btn = QPushButton("编辑链接详情")
                self.link_edit_btn.clicked.connect(self.edit_link_details)
                # 将按钮添加到内容区域
                if hasattr(self, 'content_widget') and self.content_widget.layout():
                    self.content_widget.layout().addWidget(self.link_edit_btn)
            self.link_edit_btn.setVisible(True)
        elif type_text == "语音":
            self.content_edit.setVisible(False)
            self.voice_frame.setVisible(True)
            self.content_edit.setPlaceholderText("语音录制区域")
            # 隐藏链接编辑按钮
            if hasattr(self, 'link_edit_btn'):
                self.link_edit_btn.setVisible(False)
        elif type_text == "图片":
            self.content_edit.setVisible(False)
            self.image_frame.setVisible(True)
            self.content_edit.setPlaceholderText("图片选择区域")
            # 隐藏链接编辑按钮
            if hasattr(self, 'link_edit_btn'):
                self.link_edit_btn.setVisible(False)
    
    def edit_link_details(self):
        """编辑链接详情"""
        current_content = self.content_edit.toPlainText().strip()
        
        # 创建链接编辑对话框
        link_dialog = LinkEditDialog(self, "链接详情", current_content)
        if link_dialog.exec() == QDialog.DialogCode.Accepted:
            content = link_dialog.get_link_content()
            if content:
                self.content_edit.setPlainText(content)
    
    def toggle_recording(self):
        """切换录音状态"""
        if not self.recording:
            self.start_recording()
        else:
            self.stop_recording()
    
    def start_recording(self):
        """开始录音"""
        try:
            # 创建临时录音文件
            import tempfile
            self.temp_audio_file = tempfile.NamedTemporaryFile(suffix='.mp3', delete=False)
            self.temp_audio_path = self.temp_audio_file.name
            self.temp_audio_file.close()
            
            # 初始化录音器
            self.recorder = QMediaRecorder()
            self.capture_session = QMediaCaptureSession()
            self.audio_input = QAudioInput()
            
            # 设置录音会话
            self.capture_session.setRecorder(self.recorder)
            self.capture_session.setAudioInput(self.audio_input)
            
            # 设置录音格式
            format = QMediaFormat()
            format.setFileFormat(QMediaFormat.FileFormat.MP3)
            self.recorder.setMediaFormat(format)
            
            # 设置输出文件
            self.recorder.setOutputLocation(QUrl.fromLocalFile(self.temp_audio_path))
            
            # 开始录音
            self.recorder.record()
            self.recording = True
            self.record_btn.setText("停止录音")
            self.record_btn.setStyleSheet("""
                QPushButton {
                    background-color: #dc3545;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-weight: bold;
                    padding: 6px 12px;  /* 减少内边距 */
                    font-size: 12px;  /* 减少字体 */
                }
                QPushButton:hover {
                    background-color: #c82333;
                }
            """)
            
            # 启动计时器
            self.record_seconds = 0
            self.record_timer.start(1000)  # 每秒更新一次
            self.record_progress.setVisible(True)
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"启动录音失败：{str(e)}")
    
    def stop_recording(self):
        """停止录音"""
        try:
            if self.recorder:
                self.recorder.stop()
                self.recording = False
                self.record_btn.setText("开始录音")
                self.record_btn.setStyleSheet("""
                    QPushButton {
                        background-color: #dc3545;
                        color: white;
                        border: none;
                        border-radius: 4px;
                        font-weight: bold;
                        padding: 6px 12px;  /* 减少内边距 */
                        font-size: 12px;  /* 减少字体 */
                    }
                    QPushButton:hover {
                        background-color: #c82333;
                    }
                """)
                
                # 停止计时器
                self.record_timer.stop()
                self.record_progress.setVisible(False)
                
                # 释放录音器资源
                self.recorder = None
                self.capture_session = None
                self.audio_input = None
                
                # 读取录音文件并转换为base64
                if hasattr(self, 'temp_audio_path') and os.path.exists(self.temp_audio_path):
                    try:
                        with open(self.temp_audio_path, 'rb') as f:
                            audio_data = f.read()
                            self.recorded_audio_data = base64.b64encode(audio_data).decode('utf-8')
                        
                            # 启用播放按钮
                            self.play_btn.setEnabled(True)
                        
                        QMessageBox.information(self, "成功", f"录音完成，时长：{self.record_seconds}秒")
                    except Exception as e:
                        QMessageBox.warning(self, "警告", f"读取录音文件失败：{str(e)}")
                    finally:
                        # 延迟删除临时文件，避免文件占用冲突
                        QTimer.singleShot(200, lambda: self.delete_temp_file(self.temp_audio_path))
                else:
                    QMessageBox.warning(self, "警告", "录音文件未找到")
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"停止录音失败：{str(e)}")
    
    def update_record_time(self):
        """更新录音时间"""
        self.record_seconds += 1
        self.record_time_label.setText(f"录音时长: {self.record_seconds}秒")
        self.record_progress.setValue(self.record_seconds)
        
        # 达到60秒自动停止
        if self.record_seconds >= 60:
            self.stop_recording()
    
    def play_recording(self):
        """播放录音"""
        print(f"[DEBUG] DialogueEditDialog - 开始播放录音")
        if not self.recorded_audio_data:
            print(f"[DEBUG] DialogueEditDialog - 没有录音数据")
            QMessageBox.warning(self, "警告", "没有可播放的录音！")
            return
        
        try:
            # 创建临时文件用于播放
            import tempfile
            temp_file = tempfile.NamedTemporaryFile(suffix='.mp3', delete=False)
            temp_path = temp_file.name
            temp_file.close()
            print(f"[DEBUG] DialogueEditDialog - 临时播放文件创建成功: {temp_path}")
            
            # 将base64数据写入临时文件
            audio_data = base64.b64decode(self.recorded_audio_data)
            print(f"[DEBUG] DialogueEditDialog - 解码后的音频数据大小: {len(audio_data)} 字节")
            
            with open(temp_path, 'wb') as f:
                f.write(audio_data)
            print(f"[DEBUG] DialogueEditDialog - 音频数据写入临时文件成功")
            
            # 检查文件是否存在和大小
            if os.path.exists(temp_path):
                file_size = os.path.getsize(temp_path)
                print(f"[DEBUG] DialogueEditDialog - 临时文件大小: {file_size} 字节")
            else:
                print(f"[DEBUG] DialogueEditDialog - 临时文件不存在!")
                return
            
            # 创建播放器并播放
            if not self.audio_player:
                self.audio_player = QMediaPlayer()
                print(f"[DEBUG] DialogueEditDialog - 创建新的QMediaPlayer实例")
            else:
                print(f"[DEBUG] DialogueEditDialog - 使用现有的QMediaPlayer实例")
            
            # 设置音频输出
            from PyQt6.QtMultimedia import QAudioOutput
            if not hasattr(self, 'audio_output'):
                self.audio_output = QAudioOutput()
                self.audio_player.setAudioOutput(self.audio_output)
                print(f"[DEBUG] DialogueEditDialog - 设置音频输出")
            
            # 设置音量
            self.audio_output.setVolume(1.0)  # 设置最大音量
            print(f"[DEBUG] DialogueEditDialog - 设置音量: {self.audio_output.volume()}")
            
            # 检查音频输出设备
            from PyQt6.QtMultimedia import QMediaDevices
            audio_devices = QMediaDevices.audioOutputs()
            print(f"[DEBUG] DialogueEditDialog - 可用音频输出设备数量: {len(audio_devices)}")
            for i, device in enumerate(audio_devices):
                print(f"[DEBUG] DialogueEditDialog - 音频设备 {i}: {device.description()}")
            
            # 设置默认音频输出设备
            if audio_devices:
                self.audio_output.setDevice(audio_devices[0])
                print(f"[DEBUG] DialogueEditDialog - 设置音频设备: {audio_devices[0].description()}")
            
            # 设置播放源
            self.audio_player.setSource(QUrl.fromLocalFile(temp_path))
            print(f"[DEBUG] DialogueEditDialog - 设置播放源: {temp_path}")
            
            # 连接错误信号
            self.audio_player.errorOccurred.connect(self.on_playback_error)
            
            # 连接播放状态变化信号
            self.audio_player.mediaStatusChanged.connect(self.on_media_status_changed)
            
            # 开始播放
            self.audio_player.play()
            print(f"[DEBUG] DialogueEditDialog - 开始播放")
            
            # 检查播放状态
            QTimer.singleShot(100, self.check_playback_status)
            
            # 播放完成后删除临时文件
            self.audio_player.mediaStatusChanged.connect(
                lambda status: self.on_playback_finished(status, temp_path)
            )
            
            # 更新按钮状态
            self.play_btn.setText("停止播放")
            self.play_btn.setStyleSheet("""
                QPushButton {
                    background-color: #ffc107;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    font-weight: bold;
                    padding: 6px 12px;
                    font-size: 12px;
                }
                QPushButton:hover {
                    background-color: #e0a800;
                }
            """)
            self.play_btn.clicked.disconnect()
            self.play_btn.clicked.connect(self.stop_playback)
            
        except Exception as e:
            print(f"[DEBUG] DialogueEditDialog - 播放录音失败: {str(e)}")
            QMessageBox.critical(self, "错误", f"播放录音失败：{str(e)}")
    
    def try_play_wav_format(self):
        """尝试使用WAV格式播放"""
        print(f"[DEBUG] DialogueEditDialog - 尝试使用WAV格式播放")
        try:
            # 创建WAV格式的临时文件
            import tempfile
            temp_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
            temp_path = temp_file.name
            temp_file.close()
            
            # 将base64数据写入临时文件
            audio_data = base64.b64decode(self.recorded_audio_data)
            with open(temp_path, 'wb') as f:
                f.write(audio_data)
            
            # 设置播放源为WAV文件
            self.audio_player.setSource(QUrl.fromLocalFile(temp_path))
            self.audio_player.play()
            print(f"[DEBUG] DialogueEditDialog - WAV格式播放开始")
            
        except Exception as e:
            print(f"[DEBUG] DialogueEditDialog - WAV格式播放失败: {str(e)}")
            QMessageBox.warning(self, "警告", "WAV格式播放也失败，请检查音频文件")
    
    def on_playback_error(self, error, error_string):
        """播放错误回调"""
        print(f"[DEBUG] DialogueEditDialog - 播放错误: {error}, {error_string}")
        
        # 如果是格式错误，尝试WAV格式
        if "format" in error_string.lower() or "unsupported" in error_string.lower():
            print(f"[DEBUG] DialogueEditDialog - 检测到格式错误，尝试WAV格式")
            self.try_play_wav_format()
        else:
            QMessageBox.warning(self, "播放错误", f"播放失败：{error_string}")
    
    def on_media_status_changed(self, status):
        """媒体状态变化回调"""
        status_names = {
            QMediaPlayer.MediaStatus.NoMedia: "无媒体",
            QMediaPlayer.MediaStatus.LoadingMedia: "加载中",
            QMediaPlayer.MediaStatus.LoadedMedia: "已加载",
            QMediaPlayer.MediaStatus.StalledMedia: "停滞",
            QMediaPlayer.MediaStatus.BufferingMedia: "缓冲中",
            QMediaPlayer.MediaStatus.BufferedMedia: "已缓冲",
            QMediaPlayer.MediaStatus.EndOfMedia: "播放结束",
            QMediaPlayer.MediaStatus.InvalidMedia: "无效媒体"
        }
        status_name = status_names.get(status, f"未知状态({status})")
        print(f"[DEBUG] DialogueEditDialog - 媒体状态变化: {status_name}")
        
        if status == QMediaPlayer.MediaStatus.LoadedMedia:
            print(f"[DEBUG] DialogueEditDialog - 媒体加载完成，准备播放")
        elif status == QMediaPlayer.MediaStatus.EndOfMedia:
            print(f"[DEBUG] DialogueEditDialog - 播放完成")
        elif status == QMediaPlayer.MediaStatus.InvalidMedia:
            print(f"[DEBUG] DialogueEditDialog - 无效媒体格式")
            QMessageBox.warning(self, "播放错误", "不支持的音频格式")
    
    def check_playback_status(self):
        """检查播放状态"""
        if self.audio_player:
            playback_state = self.audio_player.playbackState()
            state_names = {
                QMediaPlayer.PlaybackState.StoppedState: "已停止",
                QMediaPlayer.PlaybackState.PlayingState: "播放中",
                QMediaPlayer.PlaybackState.PausedState: "已暂停"
            }
            state_name = state_names.get(playback_state, f"未知状态({playback_state})")
            print(f"[DEBUG] DialogueEditDialog - 播放状态: {state_name}")
            
            # 检查是否有错误
            error = self.audio_player.error()
            if error != QMediaPlayer.Error.NoError:
                print(f"[DEBUG] DialogueEditDialog - 播放错误: {self.audio_player.errorString()}")
            else:
                print(f"[DEBUG] DialogueEditDialog - 播放正常")
    
    def stop_playback(self):
        """停止播放"""
        if self.audio_player:
            self.audio_player.stop()
        
        # 恢复播放按钮状态
        self.play_btn.setText("播放录音")
        self.play_btn.setStyleSheet("""
            QPushButton {
                background-color: #28a745;
                color: white;
                border: none;
                border-radius: 4px;
                font-weight: bold;
                padding: 6px 12px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #218838;
            }
        """)
        self.play_btn.clicked.disconnect()
        self.play_btn.clicked.connect(self.play_recording)
    
    def on_playback_finished(self, status, temp_path):
        """播放完成回调"""
        if status == QMediaPlayer.MediaStatus.EndOfMedia:
            # 延迟删除临时文件，避免文件占用冲突
            QTimer.singleShot(200, lambda: self.delete_temp_file(temp_path))
            
            # 恢复播放按钮状态
            self.stop_playback()
    
    def delete_temp_file(self, file_path):
        """安全删除临时文件"""
        try:
            if os.path.exists(file_path):
                os.unlink(file_path)
        except:
            pass  # 忽略删除失败的错误
    
    def select_image(self):
        """选择图片"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择图片", "", "图片文件 (*.jpg *.jpeg *.png *.gif *.bmp);;所有文件 (*)"
        )
        if file_path:
            try:
                # 读取图片文件并转换为base64
                with open(file_path, 'rb') as f:
                    image_data = f.read()
                    self.image_base64 = base64.b64encode(image_data).decode('utf-8')
                
                self.selected_image_path = file_path
                file_size = len(image_data) / 1024  # KB
                self.image_info_label.setText(f"已选择: {os.path.basename(file_path)} ({file_size:.1f} KB)")
                
            except Exception as e:
                QMessageBox.critical(self, "错误", f"读取图片失败：{str(e)}")
    
    def load_dialogue_data(self):
        """加载对话数据"""
        if self.dialogue_data:
            self.speaker_combo.setCurrentText(self.dialogue_data.get('speaker', 'A'))
            
            msg_type = self.dialogue_data.get('message_type', 'text')
            if msg_type == 'text':
                self.type_combo.setCurrentText("文本")
            elif msg_type == 'link':
                self.type_combo.setCurrentText("链接")
            elif msg_type == 'voice':
                self.type_combo.setCurrentText("语音")
            elif msg_type == 'image':
                self.type_combo.setCurrentText("图片")
            
            content = self.dialogue_data.get('content', '')
            if msg_type in ['text', 'link']:
                self.content_edit.setPlainText(content)
            elif msg_type == 'voice':
                self.recorded_audio_data = content
            elif msg_type == 'image':
                self.image_base64 = content
                if content:
                    self.image_info_label.setText("已加载图片数据")
            
            # 加载分组数据
            if self.dialogue_data.get('use_groups', False):
                self.use_groups_checkbox.setChecked(True)
                self.group_data = self.dialogue_data.get('group_data', {})
                self.refresh_groups_list()
            else:
                self.use_groups_checkbox.setChecked(False)
                self.group_data = {}
    
    def get_dialogue_data(self):
        """获取对话数据"""
        speaker = self.speaker_combo.currentText()
        msg_type_text = self.type_combo.currentText()
        
        # 转换消息类型
        if msg_type_text == "文本":
            msg_type = "text"
            content = self.content_edit.toPlainText().strip()
        elif msg_type_text == "链接":
            msg_type = "link"
            content = self.content_edit.toPlainText().strip()
        elif msg_type_text == "语音":
            msg_type = "voice"
            content = self.recorded_audio_data
        elif msg_type_text == "图片":
            msg_type = "image"
            content = self.image_base64
        else:
            msg_type = "text"
            content = ""
        
        dialogue_data = {
            "speaker": speaker,
            "message_type": msg_type
        }
        
        # 添加分组数据
        if hasattr(self, 'use_groups_checkbox') and self.use_groups_checkbox.isChecked():
            dialogue_data['use_groups'] = True
            dialogue_data['group_data'] = getattr(self, 'group_data', {})
            # 启用分组时，不设置content字段，内容在分组中设置
        else:
            dialogue_data['use_groups'] = False
            dialogue_data['group_data'] = {}
            # 未启用分组时，设置content字段
            dialogue_data['content'] = content
        
        return dialogue_data
    
    def validate_input(self):
        """验证输入"""
        msg_type_text = self.type_combo.currentText()
        
        # 如果启用了分组，验证分组数据
        if hasattr(self, 'use_groups_checkbox') and self.use_groups_checkbox.isChecked():
            if not hasattr(self, 'group_data') or not self.group_data:
                QMessageBox.warning(self, "警告", "请至少添加一个分组！")
                return False
            return True
        
        # 未启用分组时，验证消息内容
        if msg_type_text in ["文本", "链接"]:
            if not self.content_edit.toPlainText().strip():
                QMessageBox.warning(self, "警告", "请输入消息内容！")
                return False
        elif msg_type_text == "语音":
            if not self.recorded_audio_data:
                QMessageBox.warning(self, "警告", "请先录制语音！")
                return False
        elif msg_type_text == "图片":
            if not self.image_base64:
                QMessageBox.warning(self, "警告", "请先选择图片！")
                return False
        
        return True
    
    def on_groups_toggled(self, checked):
        """分组复选框状态变化处理"""
        self.groups_frame.setVisible(checked)
        
        # 当启用分组时，隐藏消息内容区域
        if checked:
            self.content_widget.setVisible(False)
            # 确保group_data存在
            if not hasattr(self, 'group_data'):
                self.group_data = {}
            self.refresh_groups_list()
        else:
            # 当禁用分组时，显示消息内容区域
            self.content_widget.setVisible(True)
    
    def refresh_groups_list(self):
        """刷新分组列表"""
        self.groups_list.clear()
        if hasattr(self, 'group_data') and self.group_data:
            for group_name, group_content in self.group_data.items():
                # 创建分组项，显示分组名称和内容预览
                display_text = f"📁 {group_name}"
                if group_content:
                    # 限制内容预览长度
                    preview = group_content[:30] + "..." if len(group_content) > 30 else group_content
                    display_text += f"\n   {preview}"
                else:
                    display_text += "\n   [空内容]"
                
                item = QListWidgetItem(display_text)
                item.setData(Qt.ItemDataRole.UserRole, group_name)  # 存储分组名称
                item.setToolTip(f"分组: {group_name}\n内容: {group_content}")
                self.groups_list.addItem(item)
        else:
            # 如果没有分组，显示提示信息
            hint_item = QListWidgetItem("📝 点击'添加分组'按钮来创建分组")
            hint_item.setFlags(hint_item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
            hint_item.setForeground(QColor("#999999"))
            self.groups_list.addItem(hint_item)
    
    def add_group(self):
        """添加分组"""
        group_name, ok = QInputDialog.getText(self, "添加分组", "请输入分组名称:")
        if ok and group_name.strip():
            if not hasattr(self, 'group_data'):
                self.group_data = {}
            
            if group_name in self.group_data:
                QMessageBox.warning(self, "警告", "分组名称已存在！")
                return
            
            # 根据消息类型设置默认内容
            msg_type = self.type_combo.currentText()
            if msg_type == "图片":
                self.group_data[group_name] = "[图片内容]"
            elif msg_type == "链接":
                self.group_data[group_name] = "[链接内容]"
            else:
                self.group_data[group_name] = ""
            
            self.refresh_groups_list()
    
    def edit_group(self):
        """编辑分组"""
        current_row = self.groups_list.currentRow()
        if current_row >= 0:
            item = self.groups_list.item(current_row)
            group_name = item.data(Qt.ItemDataRole.UserRole)  # 从UserRole获取分组名称
            if group_name and group_name in self.group_data:
                msg_type = self.type_combo.currentText()
                
                if msg_type == "图片":
                    # 图片类型：重新选择图片
                    self.edit_group_image(group_name)
                elif msg_type == "链接":
                    # 链接类型：修改链接内容
                    self.edit_group_link(group_name)
                else:
                    print('')
                    # 其他类型：使用文本编辑对话框
                content, ok = QInputDialog.getMultiLineText(
                    self, "编辑分组", f"编辑分组 '{group_name}' 的内容:", 
                    self.group_data[group_name]
                )
                if ok:
                    self.group_data[group_name] = content
                    self.refresh_groups_list()
        else:
            QMessageBox.warning(self, "警告", "请先选择要编辑的分组！")
    
    def delete_group(self):
        """删除分组"""
        current_row = self.groups_list.currentRow()
        if current_row >= 0:
            item = self.groups_list.item(current_row)
            group_name = item.data(Qt.ItemDataRole.UserRole)  # 从UserRole获取分组名称
            if group_name and group_name in self.group_data:
                reply = QMessageBox.question(
                    self, "确认删除", 
                    f"确定要删除分组 '{group_name}' 吗？",
                    QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
                )
                if reply == QMessageBox.StandardButton.Yes:
                    del self.group_data[group_name]
                    self.refresh_groups_list()
        else:
            QMessageBox.warning(self, "警告", "请先选择要删除的分组！")
    
    def edit_group_in_table(self, row):
        """在表格中编辑分组"""
        if row >= 0 and row < self.groups_list.count():
            item = self.groups_list.item(row)
            group_name = item.data(Qt.ItemDataRole.UserRole)  # 从UserRole获取分组名称
            if group_name and group_name in self.group_data:
                # 弹出编辑对话框
                content, ok = QInputDialog.getMultiLineText(
                    self, "编辑分组", f"编辑分组 '{group_name}' 的内容:", 
                    self.group_data[group_name]
                )
                if ok:
                    self.group_data[group_name] = content
                    self.refresh_groups_list()
    
    def delete_group_in_table(self, row):
        """在表格中删除分组"""
        if row >= 0 and row < self.groups_list.count():
            item = self.groups_list.item(row)
            group_name = item.data(Qt.ItemDataRole.UserRole)  # 从UserRole获取分组名称
            if group_name and group_name in self.group_data:
                reply = QMessageBox.question(
                    self, "确认删除", 
                    f"确定要删除分组 '{group_name}' 吗？",
                    QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
                )
                if reply == QMessageBox.StandardButton.Yes:
                    del self.group_data[group_name]
                    self.refresh_groups_list()

    def edit_group_image(self, group_name):
        """编辑分组图片"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, f"为分组 '{group_name}' 选择图片", "", 
            "图片文件 (*.jpg *.jpeg *.png *.gif *.bmp);;所有文件 (*)"
        )
        if file_path:
            try:
                # 读取图片文件并转换为base64
                with open(file_path, 'rb') as f:
                    image_data = f.read()
                    image_base64 = base64.b64encode(image_data).decode('utf-8')
                
                # 更新分组数据
                self.group_data[group_name] = image_base64
                self.refresh_groups_list()
                
                file_size = len(image_data) / 1024  # KB
                QMessageBox.information(self, "成功", f"已为分组 '{group_name}' 更新图片\n文件: {os.path.basename(file_path)}\n大小: {file_size:.1f} KB")
                
            except Exception as e:
                QMessageBox.critical(self, "错误", f"读取图片失败：{str(e)}")
    
    def edit_group_link(self, group_name):
        """编辑分组链接"""
        current_content = self.group_data.get(group_name, "")
        
        # 创建链接编辑对话框
        link_dialog = LinkEditDialog(self, group_name, current_content)
        if link_dialog.exec() == QDialog.DialogCode.Accepted:
            content = link_dialog.get_link_content()
            if content:
                self.group_data[group_name] = content
                self.refresh_groups_list()
    
    def on_group_item_double_clicked(self, item):
        """处理分组项双击事件"""
        group_name = item.data(Qt.ItemDataRole.UserRole)  # 从UserRole获取分组名称
        if group_name and group_name in self.group_data:
            msg_type = self.type_combo.currentText()
            
            if msg_type == "图片":
                # 图片类型：重新选择图片
                self.edit_group_image(group_name)
            elif msg_type == "链接":
                # 链接类型：修改链接内容
                self.edit_group_link(group_name)
            else:
                # 其他类型：使用文本编辑对话框
                content, ok = QInputDialog.getMultiLineText(
                    self, "编辑分组", f"编辑分组 '{group_name}' 的内容:", 
                    self.group_data[group_name]
                )
                if ok:
                    self.group_data[group_name] = content
                    self.refresh_groups_list()


class LinkEditDialog(QDialog):
    """链接编辑对话框"""
    
    def __init__(self, parent=None, group_name="", current_content=""):
        super().__init__(parent)
        self.group_name = group_name
        self.current_content = current_content
        
        self.setWindowTitle(f"编辑链接 - {group_name}")
        self.setFixedSize(700, 700)
        self.setup_ui()
        
        if current_content:
            self.load_existing_content()
    
    def setup_ui(self):
        """设置对话框UI"""
        layout = QVBoxLayout(self)
        layout.setSpacing(10)
        
        # 说明标签
        info_label = QLabel("请填写链接信息，系统将自动生成XML格式")
        info_label.setStyleSheet("color: #666; font-size: 12px;")
        layout.addWidget(info_label)
        
        # 表单布局
        form_layout = QFormLayout()
        form_layout.setSpacing(8)
        
        # 标题输入
        self.title_edit = QLineEdit()
        self.title_edit.setPlaceholderText("请输入链接标题")
        form_layout.addRow("标题:", self.title_edit)
        
        # 描述输入
        self.des_edit = QTextEdit()
        self.des_edit.setPlaceholderText("请输入链接描述")
        self.des_edit.setMaximumHeight(80)
        form_layout.addRow("描述:", self.des_edit)
        
        # URL输入
        self.url_edit = QLineEdit()
        self.url_edit.setPlaceholderText("请输入链接URL")
        form_layout.addRow("URL:", self.url_edit)
        
        layout.addLayout(form_layout)
        
        # 分隔线
        line = QFrame()
        line.setFrameShape(QFrame.Shape.HLine)
        line.setFrameShadow(QFrame.Shadow.Sunken)
        layout.addWidget(line)
        
        # 图片上传区域
        image_group = QFrame()
        image_layout = QVBoxLayout(image_group)
        image_layout.setSpacing(5)
        
        image_title = QLabel("DirectShare 图片上传")
        image_title.setStyleSheet("font-weight: bold; color: #333;")
        image_layout.addWidget(image_title)
        
        image_info = QLabel("上传图片将自动转换为base64格式并填入directshare字段")
        image_info.setStyleSheet("color: #666; font-size: 11px;")
        image_layout.addWidget(image_info)
        
        # 图片选择区域
        image_select_layout = QHBoxLayout()
        
        self.image_path_edit = QLineEdit()
        self.image_path_edit.setPlaceholderText("请选择图片文件")
        self.image_path_edit.setReadOnly(True)
        image_select_layout.addWidget(self.image_path_edit)
        
        self.select_image_btn = QPushButton("选择图片")
        self.select_image_btn.clicked.connect(self.select_image)
        image_select_layout.addWidget(self.select_image_btn)
        
        self.clear_image_btn = QPushButton("清除图片")
        self.clear_image_btn.clicked.connect(self.clear_image)
        image_select_layout.addWidget(self.clear_image_btn)
        
        image_layout.addLayout(image_select_layout)
        
        # 图片预览
        self.image_preview_label = QLabel("图片预览")
        self.image_preview_label.setFixedSize(100, 100)
        self.image_preview_label.setStyleSheet("border: 1px solid #ccc; background-color: #f9f9f9;")
        self.image_preview_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        image_layout.addWidget(self.image_preview_label)
        
        layout.addWidget(image_group)
        
        # 分隔线
        line2 = QFrame()
        line2.setFrameShape(QFrame.Shape.HLine)
        line2.setFrameShadow(QFrame.Shadow.Sunken)
        layout.addWidget(line2)
        
        # XML预览区域
        preview_label = QLabel("XML预览:")
        layout.addWidget(preview_label)
        
        self.xml_preview = QTextEdit()
        self.xml_preview.setReadOnly(True)
        self.xml_preview.setMaximumHeight(200)
        self.xml_preview.setStyleSheet("background-color: #f5f5f5; font-family: monospace; font-size: 11px;")
        layout.addWidget(self.xml_preview)
        
        # 按钮布局
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        
        self.preview_btn = QPushButton("预览XML")
        self.preview_btn.clicked.connect(self.preview_xml)
        button_layout.addWidget(self.preview_btn)
        
        self.ok_btn = QPushButton("确定")
        self.ok_btn.clicked.connect(self.accept)
        button_layout.addWidget(self.ok_btn)
        
        self.cancel_btn = QPushButton("取消")
        self.cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(self.cancel_btn)
        
        layout.addLayout(button_layout)
        
        # 连接信号以实时预览
        self.title_edit.textChanged.connect(self.preview_xml)
        self.des_edit.textChanged.connect(self.preview_xml)
        self.url_edit.textChanged.connect(self.preview_xml)
        
        # 初始化图片相关变量
        self.selected_image_base64 = ""
    
    def select_image(self):
        """选择图片文件"""
        file_path, _ = QFileDialog.getOpenFileName(
            self, 
            "选择图片文件", 
            "", 
            "图片文件 (*.jpg *.jpeg *.png *.gif *.bmp);;所有文件 (*)"
        )
        
        if file_path:
            try:
                # 读取图片文件并转换为base64
                with open(file_path, 'rb') as image_file:
                    image_data = image_file.read()
                    self.selected_image_base64 = base64.b64encode(image_data).decode('utf-8')
                
                # 更新UI
                self.image_path_edit.setText(file_path)
                
                # 显示图片预览
                from PyQt6.QtGui import QPixmap
                pixmap = QPixmap(file_path)
                if not pixmap.isNull():
                    # 缩放图片以适应预览区域
                    scaled_pixmap = pixmap.scaled(
                        98, 98, 
                        Qt.AspectRatioMode.KeepAspectRatio, 
                        Qt.TransformationMode.SmoothTransformation
                    )
                    self.image_preview_label.setPixmap(scaled_pixmap)
                else:
                    self.image_preview_label.setText("预览失败")
                
                # 更新XML预览
                self.preview_xml()
                
            except Exception as e:
                QMessageBox.warning(self, "错误", f"读取图片文件失败: {str(e)}")
    
    def clear_image(self):
        """清除已选择的图片"""
        self.selected_image_base64 = ""
        self.image_path_edit.clear()
        self.image_preview_label.clear()
        self.image_preview_label.setText("图片预览")
        self.preview_xml()
    
    def load_existing_content(self):
        """加载现有内容"""
        try:
            # 尝试解析现有的XML内容
            import xml.etree.ElementTree as ET
            root = ET.fromstring(self.current_content)
            
            # 提取标题、描述和URL
            title_elem = root.find('title')
            if title_elem is not None:
                self.title_edit.setText(title_elem.text or "")
            
            des_elem = root.find('des')
            if des_elem is not None:
                self.des_edit.setPlainText(des_elem.text or "")
            
            url_elem = root.find('url')
            if url_elem is not None:
                self.url_edit.setText(url_elem.text or "")
            
            # 提取directshare字段的base64图片数据
            directshare_elem = root.find('directshare')
            if directshare_elem is not None and directshare_elem.text:
                try:
                    # 尝试解码base64数据
                    image_data = base64.b64decode(directshare_elem.text)
                    # 如果解码成功，说明是有效的base64图片数据
                    self.selected_image_base64 = directshare_elem.text
                    self.image_path_edit.setText("已加载base64图片数据")
                    
                    # 尝试显示图片预览
                    from PyQt6.QtGui import QPixmap
                    pixmap = QPixmap()
                    if pixmap.loadFromData(image_data):
                        scaled_pixmap = pixmap.scaled(
                            98, 98, 
                            Qt.AspectRatioMode.KeepAspectRatio, 
                            Qt.TransformationMode.SmoothTransformation
                        )
                        self.image_preview_label.setPixmap(scaled_pixmap)
                    else:
                        self.image_preview_label.setText("图片预览")
                except Exception as img_error:
                    print(f"解析directshare图片数据失败: {img_error}")
                    # 如果不是有效的base64图片数据，忽略
                    pass
                
        except Exception as e:
            # 如果解析失败，清空输入框
            print(f"解析现有XML内容失败: {e}")
            self.title_edit.clear()
            self.des_edit.clear()
            self.url_edit.clear()
    
    def generate_xml(self):
        """生成XML内容"""
        title = self.title_edit.text().strip()
        des = self.des_edit.toPlainText().strip()
        url = self.url_edit.text().strip()
        # 获取directshare的base64图片数据
        directshare_content = '' # self.selected_image_base64 if self.selected_image_base64 else ''
        
        xml_template = f'''<appmsg appid="" sdkver="0">
 <title>{title}</title>
 <des>{des}</des>
 <action>view</action>
 <type>5</type>
 <showtype>0</showtype>
 <soundtype>0</soundtype>
 <mediatagname></mediatagname>
 <messageext></messageext>
 <messageaction></messageaction>
 <content></content>
 <contentattr></contentattr>
 <url>{url}</url>
 <lowurl></lowurl>
 <dataurl></dataurl>
 <lowdataurl></lowdataurl>
 <songalbumurl></songalbumurl>
 <songlyric></songlyric>
 <appattach>
 <totallen>0</totallen>
 <attachid></attachid>
 <fileext></fileext>
 <cdnthumbaeskey></cdnthumbaeskey>
 <aeskey></aeskey>
 </appattach>
 <extinfo></extinfo>
 <sourceusername></sourceusername>
 <sourcedisplayname></sourcedisplayname>
 <thumburl></thumburl>
 <md5></md5>
 <statextstr></statextstr>
 <directshare>{directshare_content}</directshare>
 </appmsg>'''
        
        return xml_template
    
    def preview_xml(self):
        """预览XML内容"""
        xml_content = self.generate_xml()
        self.xml_preview.setPlainText(xml_content)
    
    def get_link_content(self):
        """获取链接内容"""
        title = self.title_edit.text().strip()
        des = self.des_edit.toPlainText().strip()
        url = self.url_edit.text().strip()
        
        if not title or not des or not url:
            QMessageBox.warning(self, "警告", "请填写完整的链接信息（标题、描述、URL）")
            return None
        
        return self.generate_xml()


 